OLD | NEW |
| (Empty) |
1 ; | |
2 ; Copyright (c) 2013 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_idct16x16_256_add_neon_pass1| | |
12 EXPORT |vp9_idct16x16_256_add_neon_pass2| | |
13 EXPORT |vp9_idct16x16_10_add_neon_pass1| | |
14 EXPORT |vp9_idct16x16_10_add_neon_pass2| | |
15 ARM | |
16 REQUIRE8 | |
17 PRESERVE8 | |
18 | |
19 AREA ||.text||, CODE, READONLY, ALIGN=2 | |
20 | |
21 ; Transpose a 8x8 16bit data matrix. Datas are loaded in q8-q15. | |
22 MACRO | |
23 TRANSPOSE8X8 | |
24 vswp d17, d24 | |
25 vswp d23, d30 | |
26 vswp d21, d28 | |
27 vswp d19, d26 | |
28 vtrn.32 q8, q10 | |
29 vtrn.32 q9, q11 | |
30 vtrn.32 q12, q14 | |
31 vtrn.32 q13, q15 | |
32 vtrn.16 q8, q9 | |
33 vtrn.16 q10, q11 | |
34 vtrn.16 q12, q13 | |
35 vtrn.16 q14, q15 | |
36 MEND | |
37 | |
38 AREA Block, CODE, READONLY ; name this block of code | |
39 ;void |vp9_idct16x16_256_add_neon_pass1|(int16_t *input, | |
40 ; int16_t *output, int output_stride) | |
41 ; | |
42 ; r0 int16_t input | |
43 ; r1 int16_t *output | |
44 ; r2 int output_stride) | |
45 | |
46 ; idct16 stage1 - stage6 on all the elements loaded in q8-q15. The output | |
47 ; will be stored back into q8-q15 registers. This function will touch q0-q7 | |
48 ; registers and use them as buffer during calculation. | |
49 |vp9_idct16x16_256_add_neon_pass1| PROC | |
50 | |
51 ; TODO(hkuang): Find a better way to load the elements. | |
52 ; load elements of 0, 2, 4, 6, 8, 10, 12, 14 into q8 - q15 | |
53 vld2.s16 {q8,q9}, [r0]! | |
54 vld2.s16 {q9,q10}, [r0]! | |
55 vld2.s16 {q10,q11}, [r0]! | |
56 vld2.s16 {q11,q12}, [r0]! | |
57 vld2.s16 {q12,q13}, [r0]! | |
58 vld2.s16 {q13,q14}, [r0]! | |
59 vld2.s16 {q14,q15}, [r0]! | |
60 vld2.s16 {q1,q2}, [r0]! | |
61 vmov.s16 q15, q1 | |
62 | |
63 ; generate cospi_28_64 = 3196 | |
64 mov r3, #0xc00 | |
65 add r3, #0x7c | |
66 | |
67 ; generate cospi_4_64 = 16069 | |
68 mov r12, #0x3e00 | |
69 add r12, #0xc5 | |
70 | |
71 ; transpose the input data | |
72 TRANSPOSE8X8 | |
73 | |
74 ; stage 3 | |
75 vdup.16 d0, r3 ; duplicate cospi_28_64 | |
76 vdup.16 d1, r12 ; duplicate cospi_4_64 | |
77 | |
78 ; preloading to avoid stall | |
79 ; generate cospi_12_64 = 13623 | |
80 mov r3, #0x3500 | |
81 add r3, #0x37 | |
82 | |
83 ; generate cospi_20_64 = 9102 | |
84 mov r12, #0x2300 | |
85 add r12, #0x8e | |
86 | |
87 ; step2[4] * cospi_28_64 | |
88 vmull.s16 q2, d18, d0 | |
89 vmull.s16 q3, d19, d0 | |
90 | |
91 ; step2[4] * cospi_4_64 | |
92 vmull.s16 q5, d18, d1 | |
93 vmull.s16 q6, d19, d1 | |
94 | |
95 ; temp1 = step2[4] * cospi_28_64 - step2[7] * cospi_4_64 | |
96 vmlsl.s16 q2, d30, d1 | |
97 vmlsl.s16 q3, d31, d1 | |
98 | |
99 ; temp2 = step2[4] * cospi_4_64 + step2[7] * cospi_28_64 | |
100 vmlal.s16 q5, d30, d0 | |
101 vmlal.s16 q6, d31, d0 | |
102 | |
103 vdup.16 d2, r3 ; duplicate cospi_12_64 | |
104 vdup.16 d3, r12 ; duplicate cospi_20_64 | |
105 | |
106 ; dct_const_round_shift(temp1) | |
107 vqrshrn.s32 d8, q2, #14 ; >> 14 | |
108 vqrshrn.s32 d9, q3, #14 ; >> 14 | |
109 | |
110 ; dct_const_round_shift(temp2) | |
111 vqrshrn.s32 d14, q5, #14 ; >> 14 | |
112 vqrshrn.s32 d15, q6, #14 ; >> 14 | |
113 | |
114 ; preloading to avoid stall | |
115 ; generate cospi_16_64 = 11585 | |
116 mov r3, #0x2d00 | |
117 add r3, #0x41 | |
118 | |
119 ; generate cospi_24_64 = 6270 | |
120 mov r12, #0x1800 | |
121 add r12, #0x7e | |
122 | |
123 ; step2[5] * cospi_12_64 | |
124 vmull.s16 q2, d26, d2 | |
125 vmull.s16 q3, d27, d2 | |
126 | |
127 ; step2[5] * cospi_20_64 | |
128 vmull.s16 q9, d26, d3 | |
129 vmull.s16 q15, d27, d3 | |
130 | |
131 ; temp1 = input[5] * cospi_12_64 - input[3] * cospi_20_64 | |
132 vmlsl.s16 q2, d22, d3 | |
133 vmlsl.s16 q3, d23, d3 | |
134 | |
135 ; temp2 = step2[5] * cospi_20_64 + step2[6] * cospi_12_64 | |
136 vmlal.s16 q9, d22, d2 | |
137 vmlal.s16 q15, d23, d2 | |
138 | |
139 ; dct_const_round_shift(temp1) | |
140 vqrshrn.s32 d10, q2, #14 ; >> 14 | |
141 vqrshrn.s32 d11, q3, #14 ; >> 14 | |
142 | |
143 ; dct_const_round_shift(temp2) | |
144 vqrshrn.s32 d12, q9, #14 ; >> 14 | |
145 vqrshrn.s32 d13, q15, #14 ; >> 14 | |
146 | |
147 ; stage 4 | |
148 vdup.16 d30, r3 ; cospi_16_64 | |
149 | |
150 ; step1[0] * cospi_16_64 | |
151 vmull.s16 q2, d16, d30 | |
152 vmull.s16 q11, d17, d30 | |
153 | |
154 ; step1[1] * cospi_16_64 | |
155 vmull.s16 q0, d24, d30 | |
156 vmull.s16 q1, d25, d30 | |
157 | |
158 ; generate cospi_8_64 = 15137 | |
159 mov r3, #0x3b00 | |
160 add r3, #0x21 | |
161 | |
162 vdup.16 d30, r12 ; duplicate cospi_24_64 | |
163 vdup.16 d31, r3 ; duplicate cospi_8_64 | |
164 | |
165 ; temp1 = (step1[0] + step1[1]) * cospi_16_64 | |
166 vadd.s32 q3, q2, q0 | |
167 vadd.s32 q12, q11, q1 | |
168 | |
169 ; temp2 = (step1[0] - step1[1]) * cospi_16_64 | |
170 vsub.s32 q13, q2, q0 | |
171 vsub.s32 q1, q11, q1 | |
172 | |
173 ; dct_const_round_shift(temp1) | |
174 vqrshrn.s32 d16, q3, #14 ; >> 14 | |
175 vqrshrn.s32 d17, q12, #14 ; >> 14 | |
176 | |
177 ; dct_const_round_shift(temp2) | |
178 vqrshrn.s32 d18, q13, #14 ; >> 14 | |
179 vqrshrn.s32 d19, q1, #14 ; >> 14 | |
180 | |
181 ; step1[2] * cospi_24_64 - step1[3] * cospi_8_64; | |
182 ; step1[2] * cospi_8_64 | |
183 vmull.s16 q0, d20, d31 | |
184 vmull.s16 q1, d21, d31 | |
185 | |
186 ; step1[2] * cospi_24_64 | |
187 vmull.s16 q12, d20, d30 | |
188 vmull.s16 q13, d21, d30 | |
189 | |
190 ; temp2 = input[1] * cospi_8_64 + input[3] * cospi_24_64 | |
191 vmlal.s16 q0, d28, d30 | |
192 vmlal.s16 q1, d29, d30 | |
193 | |
194 ; temp1 = input[1] * cospi_24_64 - input[3] * cospi_8_64 | |
195 vmlsl.s16 q12, d28, d31 | |
196 vmlsl.s16 q13, d29, d31 | |
197 | |
198 ; dct_const_round_shift(temp2) | |
199 vqrshrn.s32 d22, q0, #14 ; >> 14 | |
200 vqrshrn.s32 d23, q1, #14 ; >> 14 | |
201 | |
202 ; dct_const_round_shift(temp1) | |
203 vqrshrn.s32 d20, q12, #14 ; >> 14 | |
204 vqrshrn.s32 d21, q13, #14 ; >> 14 | |
205 | |
206 vsub.s16 q13, q4, q5 ; step2[5] = step1[4] - step1[5]; | |
207 vadd.s16 q4, q4, q5 ; step2[4] = step1[4] + step1[5]; | |
208 vsub.s16 q14, q7, q6 ; step2[6] = -step1[6] + step1[7]; | |
209 vadd.s16 q15, q6, q7 ; step2[7] = step1[6] + step1[7]; | |
210 | |
211 ; generate cospi_16_64 = 11585 | |
212 mov r3, #0x2d00 | |
213 add r3, #0x41 | |
214 | |
215 ; stage 5 | |
216 vadd.s16 q0, q8, q11 ; step1[0] = step2[0] + step2[3]; | |
217 vadd.s16 q1, q9, q10 ; step1[1] = step2[1] + step2[2]; | |
218 vsub.s16 q2, q9, q10 ; step1[2] = step2[1] - step2[2]; | |
219 vsub.s16 q3, q8, q11 ; step1[3] = step2[0] - step2[3]; | |
220 | |
221 vdup.16 d16, r3; ; duplicate cospi_16_64 | |
222 | |
223 ; step2[5] * cospi_16_64 | |
224 vmull.s16 q11, d26, d16 | |
225 vmull.s16 q12, d27, d16 | |
226 | |
227 ; step2[6] * cospi_16_64 | |
228 vmull.s16 q9, d28, d16 | |
229 vmull.s16 q10, d29, d16 | |
230 | |
231 ; temp1 = (step2[6] - step2[5]) * cospi_16_64 | |
232 vsub.s32 q6, q9, q11 | |
233 vsub.s32 q13, q10, q12 | |
234 | |
235 ; temp2 = (step2[5] + step2[6]) * cospi_16_64 | |
236 vadd.s32 q9, q9, q11 | |
237 vadd.s32 q10, q10, q12 | |
238 | |
239 ; dct_const_round_shift(temp1) | |
240 vqrshrn.s32 d10, q6, #14 ; >> 14 | |
241 vqrshrn.s32 d11, q13, #14 ; >> 14 | |
242 | |
243 ; dct_const_round_shift(temp2) | |
244 vqrshrn.s32 d12, q9, #14 ; >> 14 | |
245 vqrshrn.s32 d13, q10, #14 ; >> 14 | |
246 | |
247 ; stage 6 | |
248 vadd.s16 q8, q0, q15 ; step2[0] = step1[0] + step1[7]; | |
249 vadd.s16 q9, q1, q6 ; step2[1] = step1[1] + step1[6]; | |
250 vadd.s16 q10, q2, q5 ; step2[2] = step1[2] + step1[5]; | |
251 vadd.s16 q11, q3, q4 ; step2[3] = step1[3] + step1[4]; | |
252 vsub.s16 q12, q3, q4 ; step2[4] = step1[3] - step1[4]; | |
253 vsub.s16 q13, q2, q5 ; step2[5] = step1[2] - step1[5]; | |
254 vsub.s16 q14, q1, q6 ; step2[6] = step1[1] - step1[6]; | |
255 vsub.s16 q15, q0, q15 ; step2[7] = step1[0] - step1[7]; | |
256 | |
257 ; store the data | |
258 vst1.64 {d16}, [r1], r2 | |
259 vst1.64 {d17}, [r1], r2 | |
260 vst1.64 {d18}, [r1], r2 | |
261 vst1.64 {d19}, [r1], r2 | |
262 vst1.64 {d20}, [r1], r2 | |
263 vst1.64 {d21}, [r1], r2 | |
264 vst1.64 {d22}, [r1], r2 | |
265 vst1.64 {d23}, [r1], r2 | |
266 vst1.64 {d24}, [r1], r2 | |
267 vst1.64 {d25}, [r1], r2 | |
268 vst1.64 {d26}, [r1], r2 | |
269 vst1.64 {d27}, [r1], r2 | |
270 vst1.64 {d28}, [r1], r2 | |
271 vst1.64 {d29}, [r1], r2 | |
272 vst1.64 {d30}, [r1], r2 | |
273 vst1.64 {d31}, [r1], r2 | |
274 | |
275 bx lr | |
276 ENDP ; |vp9_idct16x16_256_add_neon_pass1| | |
277 | |
278 ;void vp9_idct16x16_256_add_neon_pass2(int16_t *src, | |
279 ; int16_t *output, | |
280 ; int16_t *pass1Output, | |
281 ; int16_t skip_adding, | |
282 ; uint8_t *dest, | |
283 ; int dest_stride) | |
284 ; | |
285 ; r0 int16_t *src | |
286 ; r1 int16_t *output, | |
287 ; r2 int16_t *pass1Output, | |
288 ; r3 int16_t skip_adding, | |
289 ; r4 uint8_t *dest, | |
290 ; r5 int dest_stride) | |
291 | |
292 ; idct16 stage1 - stage7 on all the elements loaded in q8-q15. The output | |
293 ; will be stored back into q8-q15 registers. This function will touch q0-q7 | |
294 ; registers and use them as buffer during calculation. | |
295 |vp9_idct16x16_256_add_neon_pass2| PROC | |
296 push {r3-r9} | |
297 | |
298 ; TODO(hkuang): Find a better way to load the elements. | |
299 ; load elements of 1, 3, 5, 7, 9, 11, 13, 15 into q8 - q15 | |
300 vld2.s16 {q8,q9}, [r0]! | |
301 vld2.s16 {q9,q10}, [r0]! | |
302 vld2.s16 {q10,q11}, [r0]! | |
303 vld2.s16 {q11,q12}, [r0]! | |
304 vld2.s16 {q12,q13}, [r0]! | |
305 vld2.s16 {q13,q14}, [r0]! | |
306 vld2.s16 {q14,q15}, [r0]! | |
307 vld2.s16 {q0,q1}, [r0]! | |
308 vmov.s16 q15, q0; | |
309 | |
310 ; generate cospi_30_64 = 1606 | |
311 mov r3, #0x0600 | |
312 add r3, #0x46 | |
313 | |
314 ; generate cospi_2_64 = 16305 | |
315 mov r12, #0x3f00 | |
316 add r12, #0xb1 | |
317 | |
318 ; transpose the input data | |
319 TRANSPOSE8X8 | |
320 | |
321 ; stage 3 | |
322 vdup.16 d12, r3 ; duplicate cospi_30_64 | |
323 vdup.16 d13, r12 ; duplicate cospi_2_64 | |
324 | |
325 ; preloading to avoid stall | |
326 ; generate cospi_14_64 = 12665 | |
327 mov r3, #0x3100 | |
328 add r3, #0x79 | |
329 | |
330 ; generate cospi_18_64 = 10394 | |
331 mov r12, #0x2800 | |
332 add r12, #0x9a | |
333 | |
334 ; step1[8] * cospi_30_64 | |
335 vmull.s16 q2, d16, d12 | |
336 vmull.s16 q3, d17, d12 | |
337 | |
338 ; step1[8] * cospi_2_64 | |
339 vmull.s16 q1, d16, d13 | |
340 vmull.s16 q4, d17, d13 | |
341 | |
342 ; temp1 = step1[8] * cospi_30_64 - step1[15] * cospi_2_64 | |
343 vmlsl.s16 q2, d30, d13 | |
344 vmlsl.s16 q3, d31, d13 | |
345 | |
346 ; temp2 = step1[8] * cospi_2_64 + step1[15] * cospi_30_64 | |
347 vmlal.s16 q1, d30, d12 | |
348 vmlal.s16 q4, d31, d12 | |
349 | |
350 vdup.16 d30, r3 ; duplicate cospi_14_64 | |
351 vdup.16 d31, r12 ; duplicate cospi_18_64 | |
352 | |
353 ; dct_const_round_shift(temp1) | |
354 vqrshrn.s32 d0, q2, #14 ; >> 14 | |
355 vqrshrn.s32 d1, q3, #14 ; >> 14 | |
356 | |
357 ; dct_const_round_shift(temp2) | |
358 vqrshrn.s32 d14, q1, #14 ; >> 14 | |
359 vqrshrn.s32 d15, q4, #14 ; >> 14 | |
360 | |
361 ; preloading to avoid stall | |
362 ; generate cospi_22_64 = 7723 | |
363 mov r3, #0x1e00 | |
364 add r3, #0x2b | |
365 | |
366 ; generate cospi_10_64 = 14449 | |
367 mov r12, #0x3800 | |
368 add r12, #0x71 | |
369 | |
370 ; step1[9] * cospi_14_64 | |
371 vmull.s16 q2, d24, d30 | |
372 vmull.s16 q3, d25, d30 | |
373 | |
374 ; step1[9] * cospi_18_64 | |
375 vmull.s16 q4, d24, d31 | |
376 vmull.s16 q5, d25, d31 | |
377 | |
378 ; temp1 = step1[9] * cospi_14_64 - step1[14] * cospi_18_64 | |
379 vmlsl.s16 q2, d22, d31 | |
380 vmlsl.s16 q3, d23, d31 | |
381 | |
382 ; temp2 = step1[9] * cospi_18_64 + step1[14] * cospi_14_64 | |
383 vmlal.s16 q4, d22, d30 | |
384 vmlal.s16 q5, d23, d30 | |
385 | |
386 vdup.16 d30, r3 ; duplicate cospi_22_64 | |
387 vdup.16 d31, r12 ; duplicate cospi_10_64 | |
388 | |
389 ; dct_const_round_shift(temp1) | |
390 vqrshrn.s32 d2, q2, #14 ; >> 14 | |
391 vqrshrn.s32 d3, q3, #14 ; >> 14 | |
392 | |
393 ; dct_const_round_shift(temp2) | |
394 vqrshrn.s32 d12, q4, #14 ; >> 14 | |
395 vqrshrn.s32 d13, q5, #14 ; >> 14 | |
396 | |
397 ; step1[10] * cospi_22_64 | |
398 vmull.s16 q11, d20, d30 | |
399 vmull.s16 q12, d21, d30 | |
400 | |
401 ; step1[10] * cospi_10_64 | |
402 vmull.s16 q4, d20, d31 | |
403 vmull.s16 q5, d21, d31 | |
404 | |
405 ; temp1 = step1[10] * cospi_22_64 - step1[13] * cospi_10_64 | |
406 vmlsl.s16 q11, d26, d31 | |
407 vmlsl.s16 q12, d27, d31 | |
408 | |
409 ; temp2 = step1[10] * cospi_10_64 + step1[13] * cospi_22_64 | |
410 vmlal.s16 q4, d26, d30 | |
411 vmlal.s16 q5, d27, d30 | |
412 | |
413 ; preloading to avoid stall | |
414 ; generate cospi_6_64 = 15679 | |
415 mov r3, #0x3d00 | |
416 add r3, #0x3f | |
417 | |
418 ; generate cospi_26_64 = 4756 | |
419 mov r12, #0x1200 | |
420 add r12, #0x94 | |
421 | |
422 vdup.16 d30, r3 ; duplicate cospi_6_64 | |
423 vdup.16 d31, r12 ; duplicate cospi_26_64 | |
424 | |
425 ; dct_const_round_shift(temp1) | |
426 vqrshrn.s32 d4, q11, #14 ; >> 14 | |
427 vqrshrn.s32 d5, q12, #14 ; >> 14 | |
428 | |
429 ; dct_const_round_shift(temp2) | |
430 vqrshrn.s32 d11, q5, #14 ; >> 14 | |
431 vqrshrn.s32 d10, q4, #14 ; >> 14 | |
432 | |
433 ; step1[11] * cospi_6_64 | |
434 vmull.s16 q10, d28, d30 | |
435 vmull.s16 q11, d29, d30 | |
436 | |
437 ; step1[11] * cospi_26_64 | |
438 vmull.s16 q12, d28, d31 | |
439 vmull.s16 q13, d29, d31 | |
440 | |
441 ; temp1 = step1[11] * cospi_6_64 - step1[12] * cospi_26_64 | |
442 vmlsl.s16 q10, d18, d31 | |
443 vmlsl.s16 q11, d19, d31 | |
444 | |
445 ; temp2 = step1[11] * cospi_26_64 + step1[12] * cospi_6_64 | |
446 vmlal.s16 q12, d18, d30 | |
447 vmlal.s16 q13, d19, d30 | |
448 | |
449 vsub.s16 q9, q0, q1 ; step1[9]=step2[8]-step2[9] | |
450 vadd.s16 q0, q0, q1 ; step1[8]=step2[8]+step2[9] | |
451 | |
452 ; dct_const_round_shift(temp1) | |
453 vqrshrn.s32 d6, q10, #14 ; >> 14 | |
454 vqrshrn.s32 d7, q11, #14 ; >> 14 | |
455 | |
456 ; dct_const_round_shift(temp2) | |
457 vqrshrn.s32 d8, q12, #14 ; >> 14 | |
458 vqrshrn.s32 d9, q13, #14 ; >> 14 | |
459 | |
460 ; stage 3 | |
461 vsub.s16 q10, q3, q2 ; step1[10]=-step2[10]+step2[11] | |
462 vadd.s16 q11, q2, q3 ; step1[11]=step2[10]+step2[11] | |
463 vadd.s16 q12, q4, q5 ; step1[12]=step2[12]+step2[13] | |
464 vsub.s16 q13, q4, q5 ; step1[13]=step2[12]-step2[13] | |
465 vsub.s16 q14, q7, q6 ; step1[14]=-step2[14]+tep2[15] | |
466 vadd.s16 q7, q6, q7 ; step1[15]=step2[14]+step2[15] | |
467 | |
468 ; stage 4 | |
469 ; generate cospi_24_64 = 6270 | |
470 mov r3, #0x1800 | |
471 add r3, #0x7e | |
472 | |
473 ; generate cospi_8_64 = 15137 | |
474 mov r12, #0x3b00 | |
475 add r12, #0x21 | |
476 | |
477 ; -step1[9] * cospi_8_64 + step1[14] * cospi_24_64 | |
478 vdup.16 d30, r12 ; duplicate cospi_8_64 | |
479 vdup.16 d31, r3 ; duplicate cospi_24_64 | |
480 | |
481 ; step1[9] * cospi_24_64 | |
482 vmull.s16 q2, d18, d31 | |
483 vmull.s16 q3, d19, d31 | |
484 | |
485 ; step1[14] * cospi_24_64 | |
486 vmull.s16 q4, d28, d31 | |
487 vmull.s16 q5, d29, d31 | |
488 | |
489 ; temp2 = step1[9] * cospi_24_64 + step1[14] * cospi_8_64 | |
490 vmlal.s16 q2, d28, d30 | |
491 vmlal.s16 q3, d29, d30 | |
492 | |
493 ; temp1 = -step1[9] * cospi_8_64 + step1[14] * cospi_24_64 | |
494 vmlsl.s16 q4, d18, d30 | |
495 vmlsl.s16 q5, d19, d30 | |
496 | |
497 rsb r12, #0 | |
498 vdup.16 d30, r12 ; duplicate -cospi_8_64 | |
499 | |
500 ; dct_const_round_shift(temp2) | |
501 vqrshrn.s32 d12, q2, #14 ; >> 14 | |
502 vqrshrn.s32 d13, q3, #14 ; >> 14 | |
503 | |
504 ; dct_const_round_shift(temp1) | |
505 vqrshrn.s32 d2, q4, #14 ; >> 14 | |
506 vqrshrn.s32 d3, q5, #14 ; >> 14 | |
507 | |
508 vmov.s16 q3, q11 | |
509 vmov.s16 q4, q12 | |
510 | |
511 ; - step1[13] * cospi_8_64 | |
512 vmull.s16 q11, d26, d30 | |
513 vmull.s16 q12, d27, d30 | |
514 | |
515 ; -step1[10] * cospi_8_64 | |
516 vmull.s16 q8, d20, d30 | |
517 vmull.s16 q9, d21, d30 | |
518 | |
519 ; temp2 = -step1[10] * cospi_8_64 + step1[13] * cospi_24_64 | |
520 vmlsl.s16 q11, d20, d31 | |
521 vmlsl.s16 q12, d21, d31 | |
522 | |
523 ; temp1 = -step1[10] * cospi_8_64 + step1[13] * cospi_24_64 | |
524 vmlal.s16 q8, d26, d31 | |
525 vmlal.s16 q9, d27, d31 | |
526 | |
527 ; dct_const_round_shift(temp2) | |
528 vqrshrn.s32 d4, q11, #14 ; >> 14 | |
529 vqrshrn.s32 d5, q12, #14 ; >> 14 | |
530 | |
531 ; dct_const_round_shift(temp1) | |
532 vqrshrn.s32 d10, q8, #14 ; >> 14 | |
533 vqrshrn.s32 d11, q9, #14 ; >> 14 | |
534 | |
535 ; stage 5 | |
536 vadd.s16 q8, q0, q3 ; step1[8] = step2[8]+step2[11]; | |
537 vadd.s16 q9, q1, q2 ; step1[9] = step2[9]+step2[10]; | |
538 vsub.s16 q10, q1, q2 ; step1[10] = step2[9]-step2[10]; | |
539 vsub.s16 q11, q0, q3 ; step1[11] = step2[8]-step2[11]; | |
540 vsub.s16 q12, q7, q4 ; step1[12] =-step2[12]+step2[15]; | |
541 vsub.s16 q13, q6, q5 ; step1[13] =-step2[13]+step2[14]; | |
542 vadd.s16 q14, q6, q5 ; step1[14] =step2[13]+step2[14]; | |
543 vadd.s16 q15, q7, q4 ; step1[15] =step2[12]+step2[15]; | |
544 | |
545 ; stage 6. | |
546 ; generate cospi_16_64 = 11585 | |
547 mov r12, #0x2d00 | |
548 add r12, #0x41 | |
549 | |
550 vdup.16 d14, r12 ; duplicate cospi_16_64 | |
551 | |
552 ; step1[13] * cospi_16_64 | |
553 vmull.s16 q3, d26, d14 | |
554 vmull.s16 q4, d27, d14 | |
555 | |
556 ; step1[10] * cospi_16_64 | |
557 vmull.s16 q0, d20, d14 | |
558 vmull.s16 q1, d21, d14 | |
559 | |
560 ; temp1 = (-step1[10] + step1[13]) * cospi_16_64 | |
561 vsub.s32 q5, q3, q0 | |
562 vsub.s32 q6, q4, q1 | |
563 | |
564 ; temp2 = (step1[10] + step1[13]) * cospi_16_64 | |
565 vadd.s32 q10, q3, q0 | |
566 vadd.s32 q4, q4, q1 | |
567 | |
568 ; dct_const_round_shift(temp1) | |
569 vqrshrn.s32 d4, q5, #14 ; >> 14 | |
570 vqrshrn.s32 d5, q6, #14 ; >> 14 | |
571 | |
572 ; dct_const_round_shift(temp2) | |
573 vqrshrn.s32 d10, q10, #14 ; >> 14 | |
574 vqrshrn.s32 d11, q4, #14 ; >> 14 | |
575 | |
576 ; step1[11] * cospi_16_64 | |
577 vmull.s16 q0, d22, d14 | |
578 vmull.s16 q1, d23, d14 | |
579 | |
580 ; step1[12] * cospi_16_64 | |
581 vmull.s16 q13, d24, d14 | |
582 vmull.s16 q6, d25, d14 | |
583 | |
584 ; temp1 = (-step1[11] + step1[12]) * cospi_16_64 | |
585 vsub.s32 q10, q13, q0 | |
586 vsub.s32 q4, q6, q1 | |
587 | |
588 ; temp2 = (step1[11] + step1[12]) * cospi_16_64 | |
589 vadd.s32 q13, q13, q0 | |
590 vadd.s32 q6, q6, q1 | |
591 | |
592 ; dct_const_round_shift(temp1) | |
593 vqrshrn.s32 d6, q10, #14 ; >> 14 | |
594 vqrshrn.s32 d7, q4, #14 ; >> 14 | |
595 | |
596 ; dct_const_round_shift(temp2) | |
597 vqrshrn.s32 d8, q13, #14 ; >> 14 | |
598 vqrshrn.s32 d9, q6, #14 ; >> 14 | |
599 | |
600 mov r4, #16 ; pass1Output stride | |
601 ldr r3, [sp] ; load skip_adding | |
602 cmp r3, #0 ; check if need adding dest data | |
603 beq skip_adding_dest | |
604 | |
605 ldr r7, [sp, #28] ; dest used to save element 0-7 | |
606 mov r9, r7 ; save dest pointer for later use | |
607 ldr r8, [sp, #32] ; load dest_stride | |
608 | |
609 ; stage 7 | |
610 ; load the data in pass1 | |
611 vld1.s16 {q0}, [r2], r4 ; load data step2[0] | |
612 vld1.s16 {q1}, [r2], r4 ; load data step2[1] | |
613 vld1.s16 {q10}, [r2], r4 ; load data step2[2] | |
614 vld1.s16 {q11}, [r2], r4 ; load data step2[3] | |
615 vld1.64 {d12}, [r7], r8 ; load destinatoin data | |
616 vld1.64 {d13}, [r7], r8 ; load destinatoin data | |
617 vadd.s16 q12, q0, q15 ; step2[0] + step2[15] | |
618 vadd.s16 q13, q1, q14 ; step2[1] + step2[14] | |
619 vrshr.s16 q12, q12, #6 ; ROUND_POWER_OF_TWO | |
620 vrshr.s16 q13, q13, #6 ; ROUND_POWER_OF_TWO | |
621 vaddw.u8 q12, q12, d12 ; + dest[j * dest_stride + i] | |
622 vaddw.u8 q13, q13, d13 ; + dest[j * dest_stride + i] | |
623 vqmovun.s16 d12, q12 ; clip pixel | |
624 vqmovun.s16 d13, q13 ; clip pixel | |
625 vst1.64 {d12}, [r9], r8 ; store the data | |
626 vst1.64 {d13}, [r9], r8 ; store the data | |
627 vsub.s16 q14, q1, q14 ; step2[1] - step2[14] | |
628 vsub.s16 q15, q0, q15 ; step2[0] - step2[15] | |
629 vld1.64 {d12}, [r7], r8 ; load destinatoin data | |
630 vld1.64 {d13}, [r7], r8 ; load destinatoin data | |
631 vadd.s16 q12, q10, q5 ; step2[2] + step2[13] | |
632 vadd.s16 q13, q11, q4 ; step2[3] + step2[12] | |
633 vrshr.s16 q12, q12, #6 ; ROUND_POWER_OF_TWO | |
634 vrshr.s16 q13, q13, #6 ; ROUND_POWER_OF_TWO | |
635 vaddw.u8 q12, q12, d12 ; + dest[j * dest_stride + i] | |
636 vaddw.u8 q13, q13, d13 ; + dest[j * dest_stride + i] | |
637 vqmovun.s16 d12, q12 ; clip pixel | |
638 vqmovun.s16 d13, q13 ; clip pixel | |
639 vst1.64 {d12}, [r9], r8 ; store the data | |
640 vst1.64 {d13}, [r9], r8 ; store the data | |
641 vsub.s16 q4, q11, q4 ; step2[3] - step2[12] | |
642 vsub.s16 q5, q10, q5 ; step2[2] - step2[13] | |
643 vld1.s16 {q0}, [r2], r4 ; load data step2[4] | |
644 vld1.s16 {q1}, [r2], r4 ; load data step2[5] | |
645 vld1.s16 {q10}, [r2], r4 ; load data step2[6] | |
646 vld1.s16 {q11}, [r2], r4 ; load data step2[7] | |
647 vld1.64 {d12}, [r7], r8 ; load destinatoin data | |
648 vld1.64 {d13}, [r7], r8 ; load destinatoin data | |
649 vadd.s16 q12, q0, q3 ; step2[4] + step2[11] | |
650 vadd.s16 q13, q1, q2 ; step2[5] + step2[10] | |
651 vrshr.s16 q12, q12, #6 ; ROUND_POWER_OF_TWO | |
652 vrshr.s16 q13, q13, #6 ; ROUND_POWER_OF_TWO | |
653 vaddw.u8 q12, q12, d12 ; + dest[j * dest_stride + i] | |
654 vaddw.u8 q13, q13, d13 ; + dest[j * dest_stride + i] | |
655 vqmovun.s16 d12, q12 ; clip pixel | |
656 vqmovun.s16 d13, q13 ; clip pixel | |
657 vst1.64 {d12}, [r9], r8 ; store the data | |
658 vst1.64 {d13}, [r9], r8 ; store the data | |
659 vsub.s16 q2, q1, q2 ; step2[5] - step2[10] | |
660 vsub.s16 q3, q0, q3 ; step2[4] - step2[11] | |
661 vld1.64 {d12}, [r7], r8 ; load destinatoin data | |
662 vld1.64 {d13}, [r7], r8 ; load destinatoin data | |
663 vadd.s16 q12, q10, q9 ; step2[6] + step2[9] | |
664 vadd.s16 q13, q11, q8 ; step2[7] + step2[8] | |
665 vrshr.s16 q12, q12, #6 ; ROUND_POWER_OF_TWO | |
666 vrshr.s16 q13, q13, #6 ; ROUND_POWER_OF_TWO | |
667 vaddw.u8 q12, q12, d12 ; + dest[j * dest_stride + i] | |
668 vaddw.u8 q13, q13, d13 ; + dest[j * dest_stride + i] | |
669 vqmovun.s16 d12, q12 ; clip pixel | |
670 vqmovun.s16 d13, q13 ; clip pixel | |
671 vst1.64 {d12}, [r9], r8 ; store the data | |
672 vst1.64 {d13}, [r9], r8 ; store the data | |
673 vld1.64 {d12}, [r7], r8 ; load destinatoin data | |
674 vld1.64 {d13}, [r7], r8 ; load destinatoin data | |
675 vsub.s16 q8, q11, q8 ; step2[7] - step2[8] | |
676 vsub.s16 q9, q10, q9 ; step2[6] - step2[9] | |
677 | |
678 ; store the data output 8,9,10,11,12,13,14,15 | |
679 vrshr.s16 q8, q8, #6 ; ROUND_POWER_OF_TWO | |
680 vaddw.u8 q8, q8, d12 ; + dest[j * dest_stride + i] | |
681 vqmovun.s16 d12, q8 ; clip pixel | |
682 vst1.64 {d12}, [r9], r8 ; store the data | |
683 vld1.64 {d12}, [r7], r8 ; load destinatoin data | |
684 vrshr.s16 q9, q9, #6 | |
685 vaddw.u8 q9, q9, d13 ; + dest[j * dest_stride + i] | |
686 vqmovun.s16 d13, q9 ; clip pixel | |
687 vst1.64 {d13}, [r9], r8 ; store the data | |
688 vld1.64 {d13}, [r7], r8 ; load destinatoin data | |
689 vrshr.s16 q2, q2, #6 | |
690 vaddw.u8 q2, q2, d12 ; + dest[j * dest_stride + i] | |
691 vqmovun.s16 d12, q2 ; clip pixel | |
692 vst1.64 {d12}, [r9], r8 ; store the data | |
693 vld1.64 {d12}, [r7], r8 ; load destinatoin data | |
694 vrshr.s16 q3, q3, #6 | |
695 vaddw.u8 q3, q3, d13 ; + dest[j * dest_stride + i] | |
696 vqmovun.s16 d13, q3 ; clip pixel | |
697 vst1.64 {d13}, [r9], r8 ; store the data | |
698 vld1.64 {d13}, [r7], r8 ; load destinatoin data | |
699 vrshr.s16 q4, q4, #6 | |
700 vaddw.u8 q4, q4, d12 ; + dest[j * dest_stride + i] | |
701 vqmovun.s16 d12, q4 ; clip pixel | |
702 vst1.64 {d12}, [r9], r8 ; store the data | |
703 vld1.64 {d12}, [r7], r8 ; load destinatoin data | |
704 vrshr.s16 q5, q5, #6 | |
705 vaddw.u8 q5, q5, d13 ; + dest[j * dest_stride + i] | |
706 vqmovun.s16 d13, q5 ; clip pixel | |
707 vst1.64 {d13}, [r9], r8 ; store the data | |
708 vld1.64 {d13}, [r7], r8 ; load destinatoin data | |
709 vrshr.s16 q14, q14, #6 | |
710 vaddw.u8 q14, q14, d12 ; + dest[j * dest_stride + i] | |
711 vqmovun.s16 d12, q14 ; clip pixel | |
712 vst1.64 {d12}, [r9], r8 ; store the data | |
713 vld1.64 {d12}, [r7], r8 ; load destinatoin data | |
714 vrshr.s16 q15, q15, #6 | |
715 vaddw.u8 q15, q15, d13 ; + dest[j * dest_stride + i] | |
716 vqmovun.s16 d13, q15 ; clip pixel | |
717 vst1.64 {d13}, [r9], r8 ; store the data | |
718 b end_idct16x16_pass2 | |
719 | |
720 skip_adding_dest | |
721 ; stage 7 | |
722 ; load the data in pass1 | |
723 mov r5, #24 | |
724 mov r3, #8 | |
725 | |
726 vld1.s16 {q0}, [r2], r4 ; load data step2[0] | |
727 vld1.s16 {q1}, [r2], r4 ; load data step2[1] | |
728 vadd.s16 q12, q0, q15 ; step2[0] + step2[15] | |
729 vadd.s16 q13, q1, q14 ; step2[1] + step2[14] | |
730 vld1.s16 {q10}, [r2], r4 ; load data step2[2] | |
731 vld1.s16 {q11}, [r2], r4 ; load data step2[3] | |
732 vst1.64 {d24}, [r1], r3 ; store output[0] | |
733 vst1.64 {d25}, [r1], r5 | |
734 vst1.64 {d26}, [r1], r3 ; store output[1] | |
735 vst1.64 {d27}, [r1], r5 | |
736 vadd.s16 q12, q10, q5 ; step2[2] + step2[13] | |
737 vadd.s16 q13, q11, q4 ; step2[3] + step2[12] | |
738 vsub.s16 q14, q1, q14 ; step2[1] - step2[14] | |
739 vsub.s16 q15, q0, q15 ; step2[0] - step2[15] | |
740 vst1.64 {d24}, [r1], r3 ; store output[2] | |
741 vst1.64 {d25}, [r1], r5 | |
742 vst1.64 {d26}, [r1], r3 ; store output[3] | |
743 vst1.64 {d27}, [r1], r5 | |
744 vsub.s16 q4, q11, q4 ; step2[3] - step2[12] | |
745 vsub.s16 q5, q10, q5 ; step2[2] - step2[13] | |
746 vld1.s16 {q0}, [r2], r4 ; load data step2[4] | |
747 vld1.s16 {q1}, [r2], r4 ; load data step2[5] | |
748 vadd.s16 q12, q0, q3 ; step2[4] + step2[11] | |
749 vadd.s16 q13, q1, q2 ; step2[5] + step2[10] | |
750 vld1.s16 {q10}, [r2], r4 ; load data step2[6] | |
751 vld1.s16 {q11}, [r2], r4 ; load data step2[7] | |
752 vst1.64 {d24}, [r1], r3 ; store output[4] | |
753 vst1.64 {d25}, [r1], r5 | |
754 vst1.64 {d26}, [r1], r3 ; store output[5] | |
755 vst1.64 {d27}, [r1], r5 | |
756 vadd.s16 q12, q10, q9 ; step2[6] + step2[9] | |
757 vadd.s16 q13, q11, q8 ; step2[7] + step2[8] | |
758 vsub.s16 q2, q1, q2 ; step2[5] - step2[10] | |
759 vsub.s16 q3, q0, q3 ; step2[4] - step2[11] | |
760 vsub.s16 q8, q11, q8 ; step2[7] - step2[8] | |
761 vsub.s16 q9, q10, q9 ; step2[6] - step2[9] | |
762 vst1.64 {d24}, [r1], r3 ; store output[6] | |
763 vst1.64 {d25}, [r1], r5 | |
764 vst1.64 {d26}, [r1], r3 ; store output[7] | |
765 vst1.64 {d27}, [r1], r5 | |
766 | |
767 ; store the data output 8,9,10,11,12,13,14,15 | |
768 vst1.64 {d16}, [r1], r3 | |
769 vst1.64 {d17}, [r1], r5 | |
770 vst1.64 {d18}, [r1], r3 | |
771 vst1.64 {d19}, [r1], r5 | |
772 vst1.64 {d4}, [r1], r3 | |
773 vst1.64 {d5}, [r1], r5 | |
774 vst1.64 {d6}, [r1], r3 | |
775 vst1.64 {d7}, [r1], r5 | |
776 vst1.64 {d8}, [r1], r3 | |
777 vst1.64 {d9}, [r1], r5 | |
778 vst1.64 {d10}, [r1], r3 | |
779 vst1.64 {d11}, [r1], r5 | |
780 vst1.64 {d28}, [r1], r3 | |
781 vst1.64 {d29}, [r1], r5 | |
782 vst1.64 {d30}, [r1], r3 | |
783 vst1.64 {d31}, [r1], r5 | |
784 end_idct16x16_pass2 | |
785 pop {r3-r9} | |
786 bx lr | |
787 ENDP ; |vp9_idct16x16_256_add_neon_pass2| | |
788 | |
789 ;void |vp9_idct16x16_10_add_neon_pass1|(int16_t *input, | |
790 ; int16_t *output, int output_stride
) | |
791 ; | |
792 ; r0 int16_t input | |
793 ; r1 int16_t *output | |
794 ; r2 int output_stride) | |
795 | |
796 ; idct16 stage1 - stage6 on all the elements loaded in q8-q15. The output | |
797 ; will be stored back into q8-q15 registers. This function will touch q0-q7 | |
798 ; registers and use them as buffer during calculation. | |
799 |vp9_idct16x16_10_add_neon_pass1| PROC | |
800 | |
801 ; TODO(hkuang): Find a better way to load the elements. | |
802 ; load elements of 0, 2, 4, 6, 8, 10, 12, 14 into q8 - q15 | |
803 vld2.s16 {q8,q9}, [r0]! | |
804 vld2.s16 {q9,q10}, [r0]! | |
805 vld2.s16 {q10,q11}, [r0]! | |
806 vld2.s16 {q11,q12}, [r0]! | |
807 vld2.s16 {q12,q13}, [r0]! | |
808 vld2.s16 {q13,q14}, [r0]! | |
809 vld2.s16 {q14,q15}, [r0]! | |
810 vld2.s16 {q1,q2}, [r0]! | |
811 vmov.s16 q15, q1 | |
812 | |
813 ; generate cospi_28_64*2 = 6392 | |
814 mov r3, #0x1800 | |
815 add r3, #0xf8 | |
816 | |
817 ; generate cospi_4_64*2 = 32138 | |
818 mov r12, #0x7d00 | |
819 add r12, #0x8a | |
820 | |
821 ; transpose the input data | |
822 TRANSPOSE8X8 | |
823 | |
824 ; stage 3 | |
825 vdup.16 q0, r3 ; duplicate cospi_28_64*2 | |
826 vdup.16 q1, r12 ; duplicate cospi_4_64*2 | |
827 | |
828 ; The following instructions use vqrdmulh to do the | |
829 ; dct_const_round_shift(step2[4] * cospi_28_64). vvqrdmulh will multiply, | |
830 ; double, and return the high 16 bits, effectively giving >> 15. Doubling | |
831 ; the constant will change this to >> 14. | |
832 ; dct_const_round_shift(step2[4] * cospi_28_64); | |
833 vqrdmulh.s16 q4, q9, q0 | |
834 | |
835 ; preloading to avoid stall | |
836 ; generate cospi_16_64*2 = 23170 | |
837 mov r3, #0x5a00 | |
838 add r3, #0x82 | |
839 | |
840 ; dct_const_round_shift(step2[4] * cospi_4_64); | |
841 vqrdmulh.s16 q7, q9, q1 | |
842 | |
843 ; stage 4 | |
844 vdup.16 q1, r3 ; cospi_16_64*2 | |
845 | |
846 ; generate cospi_16_64 = 11585 | |
847 mov r3, #0x2d00 | |
848 add r3, #0x41 | |
849 | |
850 vdup.16 d4, r3; ; duplicate cospi_16_64 | |
851 | |
852 ; dct_const_round_shift(step1[0] * cospi_16_64) | |
853 vqrdmulh.s16 q8, q8, q1 | |
854 | |
855 ; step2[6] * cospi_16_64 | |
856 vmull.s16 q9, d14, d4 | |
857 vmull.s16 q10, d15, d4 | |
858 | |
859 ; step2[5] * cospi_16_64 | |
860 vmull.s16 q12, d9, d4 | |
861 vmull.s16 q11, d8, d4 | |
862 | |
863 ; temp1 = (step2[6] - step2[5]) * cospi_16_64 | |
864 vsub.s32 q15, q10, q12 | |
865 vsub.s32 q6, q9, q11 | |
866 | |
867 ; temp2 = (step2[5] + step2[6]) * cospi_16_64 | |
868 vadd.s32 q9, q9, q11 | |
869 vadd.s32 q10, q10, q12 | |
870 | |
871 ; dct_const_round_shift(temp1) | |
872 vqrshrn.s32 d11, q15, #14 ; >> 14 | |
873 vqrshrn.s32 d10, q6, #14 ; >> 14 | |
874 | |
875 ; dct_const_round_shift(temp2) | |
876 vqrshrn.s32 d12, q9, #14 ; >> 14 | |
877 vqrshrn.s32 d13, q10, #14 ; >> 14 | |
878 | |
879 ; stage 6 | |
880 vadd.s16 q2, q8, q7 ; step2[0] = step1[0] + step1[7]; | |
881 vadd.s16 q10, q8, q5 ; step2[2] = step1[2] + step1[5]; | |
882 vadd.s16 q11, q8, q4 ; step2[3] = step1[3] + step1[4]; | |
883 vadd.s16 q9, q8, q6 ; step2[1] = step1[1] + step1[6]; | |
884 vsub.s16 q12, q8, q4 ; step2[4] = step1[3] - step1[4]; | |
885 vsub.s16 q13, q8, q5 ; step2[5] = step1[2] - step1[5]; | |
886 vsub.s16 q14, q8, q6 ; step2[6] = step1[1] - step1[6]; | |
887 vsub.s16 q15, q8, q7 ; step2[7] = step1[0] - step1[7]; | |
888 | |
889 ; store the data | |
890 vst1.64 {d4}, [r1], r2 | |
891 vst1.64 {d5}, [r1], r2 | |
892 vst1.64 {d18}, [r1], r2 | |
893 vst1.64 {d19}, [r1], r2 | |
894 vst1.64 {d20}, [r1], r2 | |
895 vst1.64 {d21}, [r1], r2 | |
896 vst1.64 {d22}, [r1], r2 | |
897 vst1.64 {d23}, [r1], r2 | |
898 vst1.64 {d24}, [r1], r2 | |
899 vst1.64 {d25}, [r1], r2 | |
900 vst1.64 {d26}, [r1], r2 | |
901 vst1.64 {d27}, [r1], r2 | |
902 vst1.64 {d28}, [r1], r2 | |
903 vst1.64 {d29}, [r1], r2 | |
904 vst1.64 {d30}, [r1], r2 | |
905 vst1.64 {d31}, [r1], r2 | |
906 | |
907 bx lr | |
908 ENDP ; |vp9_idct16x16_10_add_neon_pass1| | |
909 | |
910 ;void vp9_idct16x16_10_add_neon_pass2(int16_t *src, | |
911 ; int16_t *output, | |
912 ; int16_t *pass1Output, | |
913 ; int16_t skip_adding, | |
914 ; uint8_t *dest, | |
915 ; int dest_stride) | |
916 ; | |
917 ; r0 int16_t *src | |
918 ; r1 int16_t *output, | |
919 ; r2 int16_t *pass1Output, | |
920 ; r3 int16_t skip_adding, | |
921 ; r4 uint8_t *dest, | |
922 ; r5 int dest_stride) | |
923 | |
924 ; idct16 stage1 - stage7 on all the elements loaded in q8-q15. The output | |
925 ; will be stored back into q8-q15 registers. This function will touch q0-q7 | |
926 ; registers and use them as buffer during calculation. | |
927 |vp9_idct16x16_10_add_neon_pass2| PROC | |
928 push {r3-r9} | |
929 | |
930 ; TODO(hkuang): Find a better way to load the elements. | |
931 ; load elements of 1, 3, 5, 7, 9, 11, 13, 15 into q8 - q15 | |
932 vld2.s16 {q8,q9}, [r0]! | |
933 vld2.s16 {q9,q10}, [r0]! | |
934 vld2.s16 {q10,q11}, [r0]! | |
935 vld2.s16 {q11,q12}, [r0]! | |
936 vld2.s16 {q12,q13}, [r0]! | |
937 vld2.s16 {q13,q14}, [r0]! | |
938 vld2.s16 {q14,q15}, [r0]! | |
939 vld2.s16 {q0,q1}, [r0]! | |
940 vmov.s16 q15, q0; | |
941 | |
942 ; generate 2*cospi_30_64 = 3212 | |
943 mov r3, #0xc00 | |
944 add r3, #0x8c | |
945 | |
946 ; generate 2*cospi_2_64 = 32610 | |
947 mov r12, #0x7f00 | |
948 add r12, #0x62 | |
949 | |
950 ; transpose the input data | |
951 TRANSPOSE8X8 | |
952 | |
953 ; stage 3 | |
954 vdup.16 q6, r3 ; duplicate 2*cospi_30_64 | |
955 | |
956 ; dct_const_round_shift(step1[8] * cospi_30_64) | |
957 vqrdmulh.s16 q0, q8, q6 | |
958 | |
959 vdup.16 q6, r12 ; duplicate 2*cospi_2_64 | |
960 | |
961 ; dct_const_round_shift(step1[8] * cospi_2_64) | |
962 vqrdmulh.s16 q7, q8, q6 | |
963 | |
964 ; preloading to avoid stall | |
965 ; generate 2*cospi_26_64 = 9512 | |
966 mov r12, #0x2500 | |
967 add r12, #0x28 | |
968 rsb r12, #0 | |
969 vdup.16 q15, r12 ; duplicate -2*cospi_26_64 | |
970 | |
971 ; generate 2*cospi_6_64 = 31358 | |
972 mov r3, #0x7a00 | |
973 add r3, #0x7e | |
974 vdup.16 q14, r3 ; duplicate 2*cospi_6_64 | |
975 | |
976 ; dct_const_round_shift(- step1[12] * cospi_26_64) | |
977 vqrdmulh.s16 q3, q9, q15 | |
978 | |
979 ; dct_const_round_shift(step1[12] * cospi_6_64) | |
980 vqrdmulh.s16 q4, q9, q14 | |
981 | |
982 ; stage 4 | |
983 ; generate cospi_24_64 = 6270 | |
984 mov r3, #0x1800 | |
985 add r3, #0x7e | |
986 vdup.16 d31, r3 ; duplicate cospi_24_64 | |
987 | |
988 ; generate cospi_8_64 = 15137 | |
989 mov r12, #0x3b00 | |
990 add r12, #0x21 | |
991 vdup.16 d30, r12 ; duplicate cospi_8_64 | |
992 | |
993 ; step1[14] * cospi_24_64 | |
994 vmull.s16 q12, d14, d31 | |
995 vmull.s16 q5, d15, d31 | |
996 | |
997 ; step1[9] * cospi_24_64 | |
998 vmull.s16 q2, d0, d31 | |
999 vmull.s16 q11, d1, d31 | |
1000 | |
1001 ; temp1 = -step1[9] * cospi_8_64 + step1[14] * cospi_24_64 | |
1002 vmlsl.s16 q12, d0, d30 | |
1003 vmlsl.s16 q5, d1, d30 | |
1004 | |
1005 ; temp2 = step1[9] * cospi_24_64 + step1[14] * cospi_8_64 | |
1006 vmlal.s16 q2, d14, d30 | |
1007 vmlal.s16 q11, d15, d30 | |
1008 | |
1009 rsb r12, #0 | |
1010 vdup.16 d30, r12 ; duplicate -cospi_8_64 | |
1011 | |
1012 ; dct_const_round_shift(temp1) | |
1013 vqrshrn.s32 d2, q12, #14 ; >> 14 | |
1014 vqrshrn.s32 d3, q5, #14 ; >> 14 | |
1015 | |
1016 ; dct_const_round_shift(temp2) | |
1017 vqrshrn.s32 d12, q2, #14 ; >> 14 | |
1018 vqrshrn.s32 d13, q11, #14 ; >> 14 | |
1019 | |
1020 ; - step1[13] * cospi_8_64 | |
1021 vmull.s16 q10, d8, d30 | |
1022 vmull.s16 q13, d9, d30 | |
1023 | |
1024 ; -step1[10] * cospi_8_64 | |
1025 vmull.s16 q8, d6, d30 | |
1026 vmull.s16 q9, d7, d30 | |
1027 | |
1028 ; temp1 = -step1[10] * cospi_24_64 - step1[13] * cospi_8_64 | |
1029 vmlsl.s16 q10, d6, d31 | |
1030 vmlsl.s16 q13, d7, d31 | |
1031 | |
1032 ; temp2 = -step1[10] * cospi_8_64 + step1[13] * cospi_24_64 | |
1033 vmlal.s16 q8, d8, d31 | |
1034 vmlal.s16 q9, d9, d31 | |
1035 | |
1036 ; dct_const_round_shift(temp1) | |
1037 vqrshrn.s32 d4, q10, #14 ; >> 14 | |
1038 vqrshrn.s32 d5, q13, #14 ; >> 14 | |
1039 | |
1040 ; dct_const_round_shift(temp2) | |
1041 vqrshrn.s32 d10, q8, #14 ; >> 14 | |
1042 vqrshrn.s32 d11, q9, #14 ; >> 14 | |
1043 | |
1044 ; stage 5 | |
1045 vadd.s16 q8, q0, q3 ; step1[8] = step2[8]+step2[11]; | |
1046 vadd.s16 q9, q1, q2 ; step1[9] = step2[9]+step2[10]; | |
1047 vsub.s16 q10, q1, q2 ; step1[10] = step2[9]-step2[10]; | |
1048 vsub.s16 q11, q0, q3 ; step1[11] = step2[8]-step2[11]; | |
1049 vsub.s16 q12, q7, q4 ; step1[12] =-step2[12]+step2[15]; | |
1050 vsub.s16 q13, q6, q5 ; step1[13] =-step2[13]+step2[14]; | |
1051 vadd.s16 q14, q6, q5 ; step1[14] =step2[13]+step2[14]; | |
1052 vadd.s16 q15, q7, q4 ; step1[15] =step2[12]+step2[15]; | |
1053 | |
1054 ; stage 6. | |
1055 ; generate cospi_16_64 = 11585 | |
1056 mov r12, #0x2d00 | |
1057 add r12, #0x41 | |
1058 | |
1059 vdup.16 d14, r12 ; duplicate cospi_16_64 | |
1060 | |
1061 ; step1[13] * cospi_16_64 | |
1062 vmull.s16 q3, d26, d14 | |
1063 vmull.s16 q4, d27, d14 | |
1064 | |
1065 ; step1[10] * cospi_16_64 | |
1066 vmull.s16 q0, d20, d14 | |
1067 vmull.s16 q1, d21, d14 | |
1068 | |
1069 ; temp1 = (-step1[10] + step1[13]) * cospi_16_64 | |
1070 vsub.s32 q5, q3, q0 | |
1071 vsub.s32 q6, q4, q1 | |
1072 | |
1073 ; temp2 = (step1[10] + step1[13]) * cospi_16_64 | |
1074 vadd.s32 q0, q3, q0 | |
1075 vadd.s32 q1, q4, q1 | |
1076 | |
1077 ; dct_const_round_shift(temp1) | |
1078 vqrshrn.s32 d4, q5, #14 ; >> 14 | |
1079 vqrshrn.s32 d5, q6, #14 ; >> 14 | |
1080 | |
1081 ; dct_const_round_shift(temp2) | |
1082 vqrshrn.s32 d10, q0, #14 ; >> 14 | |
1083 vqrshrn.s32 d11, q1, #14 ; >> 14 | |
1084 | |
1085 ; step1[11] * cospi_16_64 | |
1086 vmull.s16 q0, d22, d14 | |
1087 vmull.s16 q1, d23, d14 | |
1088 | |
1089 ; step1[12] * cospi_16_64 | |
1090 vmull.s16 q13, d24, d14 | |
1091 vmull.s16 q6, d25, d14 | |
1092 | |
1093 ; temp1 = (-step1[11] + step1[12]) * cospi_16_64 | |
1094 vsub.s32 q10, q13, q0 | |
1095 vsub.s32 q4, q6, q1 | |
1096 | |
1097 ; temp2 = (step1[11] + step1[12]) * cospi_16_64 | |
1098 vadd.s32 q13, q13, q0 | |
1099 vadd.s32 q6, q6, q1 | |
1100 | |
1101 ; dct_const_round_shift(input_dc * cospi_16_64) | |
1102 vqrshrn.s32 d6, q10, #14 ; >> 14 | |
1103 vqrshrn.s32 d7, q4, #14 ; >> 14 | |
1104 | |
1105 ; dct_const_round_shift((step1[11] + step1[12]) * cospi_16_64); | |
1106 vqrshrn.s32 d8, q13, #14 ; >> 14 | |
1107 vqrshrn.s32 d9, q6, #14 ; >> 14 | |
1108 | |
1109 mov r4, #16 ; pass1Output stride | |
1110 ldr r3, [sp] ; load skip_adding | |
1111 | |
1112 ; stage 7 | |
1113 ; load the data in pass1 | |
1114 mov r5, #24 | |
1115 mov r3, #8 | |
1116 | |
1117 vld1.s16 {q0}, [r2], r4 ; load data step2[0] | |
1118 vld1.s16 {q1}, [r2], r4 ; load data step2[1] | |
1119 vadd.s16 q12, q0, q15 ; step2[0] + step2[15] | |
1120 vadd.s16 q13, q1, q14 ; step2[1] + step2[14] | |
1121 vld1.s16 {q10}, [r2], r4 ; load data step2[2] | |
1122 vld1.s16 {q11}, [r2], r4 ; load data step2[3] | |
1123 vst1.64 {d24}, [r1], r3 ; store output[0] | |
1124 vst1.64 {d25}, [r1], r5 | |
1125 vst1.64 {d26}, [r1], r3 ; store output[1] | |
1126 vst1.64 {d27}, [r1], r5 | |
1127 vadd.s16 q12, q10, q5 ; step2[2] + step2[13] | |
1128 vadd.s16 q13, q11, q4 ; step2[3] + step2[12] | |
1129 vsub.s16 q14, q1, q14 ; step2[1] - step2[14] | |
1130 vsub.s16 q15, q0, q15 ; step2[0] - step2[15] | |
1131 vst1.64 {d24}, [r1], r3 ; store output[2] | |
1132 vst1.64 {d25}, [r1], r5 | |
1133 vst1.64 {d26}, [r1], r3 ; store output[3] | |
1134 vst1.64 {d27}, [r1], r5 | |
1135 vsub.s16 q4, q11, q4 ; step2[3] - step2[12] | |
1136 vsub.s16 q5, q10, q5 ; step2[2] - step2[13] | |
1137 vld1.s16 {q0}, [r2], r4 ; load data step2[4] | |
1138 vld1.s16 {q1}, [r2], r4 ; load data step2[5] | |
1139 vadd.s16 q12, q0, q3 ; step2[4] + step2[11] | |
1140 vadd.s16 q13, q1, q2 ; step2[5] + step2[10] | |
1141 vld1.s16 {q10}, [r2], r4 ; load data step2[6] | |
1142 vld1.s16 {q11}, [r2], r4 ; load data step2[7] | |
1143 vst1.64 {d24}, [r1], r3 ; store output[4] | |
1144 vst1.64 {d25}, [r1], r5 | |
1145 vst1.64 {d26}, [r1], r3 ; store output[5] | |
1146 vst1.64 {d27}, [r1], r5 | |
1147 vadd.s16 q12, q10, q9 ; step2[6] + step2[9] | |
1148 vadd.s16 q13, q11, q8 ; step2[7] + step2[8] | |
1149 vsub.s16 q2, q1, q2 ; step2[5] - step2[10] | |
1150 vsub.s16 q3, q0, q3 ; step2[4] - step2[11] | |
1151 vsub.s16 q8, q11, q8 ; step2[7] - step2[8] | |
1152 vsub.s16 q9, q10, q9 ; step2[6] - step2[9] | |
1153 vst1.64 {d24}, [r1], r3 ; store output[6] | |
1154 vst1.64 {d25}, [r1], r5 | |
1155 vst1.64 {d26}, [r1], r3 ; store output[7] | |
1156 vst1.64 {d27}, [r1], r5 | |
1157 | |
1158 ; store the data output 8,9,10,11,12,13,14,15 | |
1159 vst1.64 {d16}, [r1], r3 | |
1160 vst1.64 {d17}, [r1], r5 | |
1161 vst1.64 {d18}, [r1], r3 | |
1162 vst1.64 {d19}, [r1], r5 | |
1163 vst1.64 {d4}, [r1], r3 | |
1164 vst1.64 {d5}, [r1], r5 | |
1165 vst1.64 {d6}, [r1], r3 | |
1166 vst1.64 {d7}, [r1], r5 | |
1167 vst1.64 {d8}, [r1], r3 | |
1168 vst1.64 {d9}, [r1], r5 | |
1169 vst1.64 {d10}, [r1], r3 | |
1170 vst1.64 {d11}, [r1], r5 | |
1171 vst1.64 {d28}, [r1], r3 | |
1172 vst1.64 {d29}, [r1], r5 | |
1173 vst1.64 {d30}, [r1], r3 | |
1174 vst1.64 {d31}, [r1], r5 | |
1175 end_idct10_16x16_pass2 | |
1176 pop {r3-r9} | |
1177 bx lr | |
1178 ENDP ; |vp9_idct16x16_10_add_neon_pass2| | |
1179 END | |
OLD | NEW |