Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(171)

Side by Side Diff: source/libvpx/vp9/common/arm/neon/vp9_idct8x8_add_neon.asm

Issue 812033011: libvpx: Pull from upstream (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/libvpx/
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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_idct8x8_64_add_neon|
12 EXPORT |vp9_idct8x8_12_add_neon|
13 ARM
14 REQUIRE8
15 PRESERVE8
16
17 AREA ||.text||, CODE, READONLY, ALIGN=2
18
19 ; Parallel 1D IDCT on all the columns of a 8x8 16bit data matrix which are
20 ; loaded in q8-q15. The output will be stored back into q8-q15 registers.
21 ; This macro will touch q0-q7 registers and use them as buffer during
22 ; calculation.
23 MACRO
24 IDCT8x8_1D
25 ; stage 1
26 vdup.16 d0, r3 ; duplicate cospi_28_64
27 vdup.16 d1, r4 ; duplicate cospi_4_64
28 vdup.16 d2, r5 ; duplicate cospi_12_64
29 vdup.16 d3, r6 ; duplicate cospi_20_64
30
31 ; input[1] * cospi_28_64
32 vmull.s16 q2, d18, d0
33 vmull.s16 q3, d19, d0
34
35 ; input[5] * cospi_12_64
36 vmull.s16 q5, d26, d2
37 vmull.s16 q6, d27, d2
38
39 ; input[1]*cospi_28_64-input[7]*cospi_4_64
40 vmlsl.s16 q2, d30, d1
41 vmlsl.s16 q3, d31, d1
42
43 ; input[5] * cospi_12_64 - input[3] * cospi_20_64
44 vmlsl.s16 q5, d22, d3
45 vmlsl.s16 q6, d23, d3
46
47 ; dct_const_round_shift(input_dc * cospi_16_64)
48 vqrshrn.s32 d8, q2, #14 ; >> 14
49 vqrshrn.s32 d9, q3, #14 ; >> 14
50
51 ; dct_const_round_shift(input_dc * cospi_16_64)
52 vqrshrn.s32 d10, q5, #14 ; >> 14
53 vqrshrn.s32 d11, q6, #14 ; >> 14
54
55 ; input[1] * cospi_4_64
56 vmull.s16 q2, d18, d1
57 vmull.s16 q3, d19, d1
58
59 ; input[5] * cospi_20_64
60 vmull.s16 q9, d26, d3
61 vmull.s16 q13, d27, d3
62
63 ; input[1]*cospi_4_64+input[7]*cospi_28_64
64 vmlal.s16 q2, d30, d0
65 vmlal.s16 q3, d31, d0
66
67 ; input[5] * cospi_20_64 + input[3] * cospi_12_64
68 vmlal.s16 q9, d22, d2
69 vmlal.s16 q13, d23, d2
70
71 ; dct_const_round_shift(input_dc * cospi_16_64)
72 vqrshrn.s32 d14, q2, #14 ; >> 14
73 vqrshrn.s32 d15, q3, #14 ; >> 14
74
75 ; stage 2 & stage 3 - even half
76 vdup.16 d0, r7 ; duplicate cospi_16_64
77
78 ; dct_const_round_shift(input_dc * cospi_16_64)
79 vqrshrn.s32 d12, q9, #14 ; >> 14
80 vqrshrn.s32 d13, q13, #14 ; >> 14
81
82 ; input[0] * cospi_16_64
83 vmull.s16 q2, d16, d0
84 vmull.s16 q3, d17, d0
85
86 ; input[0] * cospi_16_64
87 vmull.s16 q13, d16, d0
88 vmull.s16 q15, d17, d0
89
90 ; (input[0] + input[2]) * cospi_16_64
91 vmlal.s16 q2, d24, d0
92 vmlal.s16 q3, d25, d0
93
94 ; (input[0] - input[2]) * cospi_16_64
95 vmlsl.s16 q13, d24, d0
96 vmlsl.s16 q15, d25, d0
97
98 vdup.16 d0, r8 ; duplicate cospi_24_64
99 vdup.16 d1, r9 ; duplicate cospi_8_64
100
101 ; dct_const_round_shift(input_dc * cospi_16_64)
102 vqrshrn.s32 d18, q2, #14 ; >> 14
103 vqrshrn.s32 d19, q3, #14 ; >> 14
104
105 ; dct_const_round_shift(input_dc * cospi_16_64)
106 vqrshrn.s32 d22, q13, #14 ; >> 14
107 vqrshrn.s32 d23, q15, #14 ; >> 14
108
109 ; input[1] * cospi_24_64 - input[3] * cospi_8_64
110 ; input[1] * cospi_24_64
111 vmull.s16 q2, d20, d0
112 vmull.s16 q3, d21, d0
113
114 ; input[1] * cospi_8_64
115 vmull.s16 q8, d20, d1
116 vmull.s16 q12, d21, d1
117
118 ; input[1] * cospi_24_64 - input[3] * cospi_8_64
119 vmlsl.s16 q2, d28, d1
120 vmlsl.s16 q3, d29, d1
121
122 ; input[1] * cospi_8_64 + input[3] * cospi_24_64
123 vmlal.s16 q8, d28, d0
124 vmlal.s16 q12, d29, d0
125
126 ; dct_const_round_shift(input_dc * cospi_16_64)
127 vqrshrn.s32 d26, q2, #14 ; >> 14
128 vqrshrn.s32 d27, q3, #14 ; >> 14
129
130 ; dct_const_round_shift(input_dc * cospi_16_64)
131 vqrshrn.s32 d30, q8, #14 ; >> 14
132 vqrshrn.s32 d31, q12, #14 ; >> 14
133
134 vadd.s16 q0, q9, q15 ; output[0] = step[0] + step[3]
135 vadd.s16 q1, q11, q13 ; output[1] = step[1] + step[2]
136 vsub.s16 q2, q11, q13 ; output[2] = step[1] - step[2]
137 vsub.s16 q3, q9, q15 ; output[3] = step[0] - step[3]
138
139 ; stage 3 -odd half
140 vdup.16 d16, r7 ; duplicate cospi_16_64
141
142 ; stage 2 - odd half
143 vsub.s16 q13, q4, q5 ; step2[5] = step1[4] - step1[5]
144 vadd.s16 q4, q4, q5 ; step2[4] = step1[4] + step1[5]
145 vsub.s16 q14, q7, q6 ; step2[6] = -step1[6] + step1[7]
146 vadd.s16 q7, q7, q6 ; step2[7] = step1[6] + step1[7]
147
148 ; step2[6] * cospi_16_64
149 vmull.s16 q9, d28, d16
150 vmull.s16 q10, d29, d16
151
152 ; step2[6] * cospi_16_64
153 vmull.s16 q11, d28, d16
154 vmull.s16 q12, d29, d16
155
156 ; (step2[6] - step2[5]) * cospi_16_64
157 vmlsl.s16 q9, d26, d16
158 vmlsl.s16 q10, d27, d16
159
160 ; (step2[5] + step2[6]) * cospi_16_64
161 vmlal.s16 q11, d26, d16
162 vmlal.s16 q12, d27, d16
163
164 ; dct_const_round_shift(input_dc * cospi_16_64)
165 vqrshrn.s32 d10, q9, #14 ; >> 14
166 vqrshrn.s32 d11, q10, #14 ; >> 14
167
168 ; dct_const_round_shift(input_dc * cospi_16_64)
169 vqrshrn.s32 d12, q11, #14 ; >> 14
170 vqrshrn.s32 d13, q12, #14 ; >> 14
171
172 ; stage 4
173 vadd.s16 q8, q0, q7 ; output[0] = step1[0] + step1[7];
174 vadd.s16 q9, q1, q6 ; output[1] = step1[1] + step1[6];
175 vadd.s16 q10, q2, q5 ; output[2] = step1[2] + step1[5];
176 vadd.s16 q11, q3, q4 ; output[3] = step1[3] + step1[4];
177 vsub.s16 q12, q3, q4 ; output[4] = step1[3] - step1[4];
178 vsub.s16 q13, q2, q5 ; output[5] = step1[2] - step1[5];
179 vsub.s16 q14, q1, q6 ; output[6] = step1[1] - step1[6];
180 vsub.s16 q15, q0, q7 ; output[7] = step1[0] - step1[7];
181 MEND
182
183 ; Transpose a 8x8 16bit data matrix. Datas are loaded in q8-q15.
184 MACRO
185 TRANSPOSE8X8
186 vswp d17, d24
187 vswp d23, d30
188 vswp d21, d28
189 vswp d19, d26
190 vtrn.32 q8, q10
191 vtrn.32 q9, q11
192 vtrn.32 q12, q14
193 vtrn.32 q13, q15
194 vtrn.16 q8, q9
195 vtrn.16 q10, q11
196 vtrn.16 q12, q13
197 vtrn.16 q14, q15
198 MEND
199
200 AREA Block, CODE, READONLY ; name this block of code
201 ;void vp9_idct8x8_64_add_neon(int16_t *input, uint8_t *dest, int dest_stride)
202 ;
203 ; r0 int16_t input
204 ; r1 uint8_t *dest
205 ; r2 int dest_stride)
206
207 |vp9_idct8x8_64_add_neon| PROC
208 push {r4-r9}
209 vpush {d8-d15}
210 vld1.s16 {q8,q9}, [r0]!
211 vld1.s16 {q10,q11}, [r0]!
212 vld1.s16 {q12,q13}, [r0]!
213 vld1.s16 {q14,q15}, [r0]!
214
215 ; transpose the input data
216 TRANSPOSE8X8
217
218 ; generate cospi_28_64 = 3196
219 mov r3, #0x0c00
220 add r3, #0x7c
221
222 ; generate cospi_4_64 = 16069
223 mov r4, #0x3e00
224 add r4, #0xc5
225
226 ; generate cospi_12_64 = 13623
227 mov r5, #0x3500
228 add r5, #0x37
229
230 ; generate cospi_20_64 = 9102
231 mov r6, #0x2300
232 add r6, #0x8e
233
234 ; generate cospi_16_64 = 11585
235 mov r7, #0x2d00
236 add r7, #0x41
237
238 ; generate cospi_24_64 = 6270
239 mov r8, #0x1800
240 add r8, #0x7e
241
242 ; generate cospi_8_64 = 15137
243 mov r9, #0x3b00
244 add r9, #0x21
245
246 ; First transform rows
247 IDCT8x8_1D
248
249 ; Transpose the matrix
250 TRANSPOSE8X8
251
252 ; Then transform columns
253 IDCT8x8_1D
254
255 ; ROUND_POWER_OF_TWO(temp_out[j], 5)
256 vrshr.s16 q8, q8, #5
257 vrshr.s16 q9, q9, #5
258 vrshr.s16 q10, q10, #5
259 vrshr.s16 q11, q11, #5
260 vrshr.s16 q12, q12, #5
261 vrshr.s16 q13, q13, #5
262 vrshr.s16 q14, q14, #5
263 vrshr.s16 q15, q15, #5
264
265 ; save dest pointer
266 mov r0, r1
267
268 ; load destination data
269 vld1.64 {d0}, [r1], r2
270 vld1.64 {d1}, [r1], r2
271 vld1.64 {d2}, [r1], r2
272 vld1.64 {d3}, [r1], r2
273 vld1.64 {d4}, [r1], r2
274 vld1.64 {d5}, [r1], r2
275 vld1.64 {d6}, [r1], r2
276 vld1.64 {d7}, [r1]
277
278 ; ROUND_POWER_OF_TWO(temp_out[j], 5) + dest[j * dest_stride + i]
279 vaddw.u8 q8, q8, d0
280 vaddw.u8 q9, q9, d1
281 vaddw.u8 q10, q10, d2
282 vaddw.u8 q11, q11, d3
283 vaddw.u8 q12, q12, d4
284 vaddw.u8 q13, q13, d5
285 vaddw.u8 q14, q14, d6
286 vaddw.u8 q15, q15, d7
287
288 ; clip_pixel
289 vqmovun.s16 d0, q8
290 vqmovun.s16 d1, q9
291 vqmovun.s16 d2, q10
292 vqmovun.s16 d3, q11
293 vqmovun.s16 d4, q12
294 vqmovun.s16 d5, q13
295 vqmovun.s16 d6, q14
296 vqmovun.s16 d7, q15
297
298 ; store the data
299 vst1.64 {d0}, [r0], r2
300 vst1.64 {d1}, [r0], r2
301 vst1.64 {d2}, [r0], r2
302 vst1.64 {d3}, [r0], r2
303 vst1.64 {d4}, [r0], r2
304 vst1.64 {d5}, [r0], r2
305 vst1.64 {d6}, [r0], r2
306 vst1.64 {d7}, [r0], r2
307
308 vpop {d8-d15}
309 pop {r4-r9}
310 bx lr
311 ENDP ; |vp9_idct8x8_64_add_neon|
312
313 ;void vp9_idct8x8_12_add_neon(int16_t *input, uint8_t *dest, int dest_stride)
314 ;
315 ; r0 int16_t input
316 ; r1 uint8_t *dest
317 ; r2 int dest_stride)
318
319 |vp9_idct8x8_12_add_neon| PROC
320 push {r4-r9}
321 vpush {d8-d15}
322 vld1.s16 {q8,q9}, [r0]!
323 vld1.s16 {q10,q11}, [r0]!
324 vld1.s16 {q12,q13}, [r0]!
325 vld1.s16 {q14,q15}, [r0]!
326
327 ; transpose the input data
328 TRANSPOSE8X8
329
330 ; generate cospi_28_64 = 3196
331 mov r3, #0x0c00
332 add r3, #0x7c
333
334 ; generate cospi_4_64 = 16069
335 mov r4, #0x3e00
336 add r4, #0xc5
337
338 ; generate cospi_12_64 = 13623
339 mov r5, #0x3500
340 add r5, #0x37
341
342 ; generate cospi_20_64 = 9102
343 mov r6, #0x2300
344 add r6, #0x8e
345
346 ; generate cospi_16_64 = 11585
347 mov r7, #0x2d00
348 add r7, #0x41
349
350 ; generate cospi_24_64 = 6270
351 mov r8, #0x1800
352 add r8, #0x7e
353
354 ; generate cospi_8_64 = 15137
355 mov r9, #0x3b00
356 add r9, #0x21
357
358 ; First transform rows
359 ; stage 1
360 ; The following instructions use vqrdmulh to do the
361 ; dct_const_round_shift(input[1] * cospi_28_64). vqrdmulh will do doubling
362 ; multiply and shift the result by 16 bits instead of 14 bits. So we need
363 ; to double the constants before multiplying to compensate this.
364 mov r12, r3, lsl #1
365 vdup.16 q0, r12 ; duplicate cospi_28_64*2
366 mov r12, r4, lsl #1
367 vdup.16 q1, r12 ; duplicate cospi_4_64*2
368
369 ; dct_const_round_shift(input[1] * cospi_28_64)
370 vqrdmulh.s16 q4, q9, q0
371
372 mov r12, r6, lsl #1
373 rsb r12, #0
374 vdup.16 q0, r12 ; duplicate -cospi_20_64*2
375
376 ; dct_const_round_shift(input[1] * cospi_4_64)
377 vqrdmulh.s16 q7, q9, q1
378
379 mov r12, r5, lsl #1
380 vdup.16 q1, r12 ; duplicate cospi_12_64*2
381
382 ; dct_const_round_shift(- input[3] * cospi_20_64)
383 vqrdmulh.s16 q5, q11, q0
384
385 mov r12, r7, lsl #1
386 vdup.16 q0, r12 ; duplicate cospi_16_64*2
387
388 ; dct_const_round_shift(input[3] * cospi_12_64)
389 vqrdmulh.s16 q6, q11, q1
390
391 ; stage 2 & stage 3 - even half
392 mov r12, r8, lsl #1
393 vdup.16 q1, r12 ; duplicate cospi_24_64*2
394
395 ; dct_const_round_shift(input_dc * cospi_16_64)
396 vqrdmulh.s16 q9, q8, q0
397
398 mov r12, r9, lsl #1
399 vdup.16 q0, r12 ; duplicate cospi_8_64*2
400
401 ; dct_const_round_shift(input[1] * cospi_24_64)
402 vqrdmulh.s16 q13, q10, q1
403
404 ; dct_const_round_shift(input[1] * cospi_8_64)
405 vqrdmulh.s16 q15, q10, q0
406
407 ; stage 3 -odd half
408 vdup.16 d16, r7 ; duplicate cospi_16_64
409
410 vadd.s16 q0, q9, q15 ; output[0] = step[0] + step[3]
411 vadd.s16 q1, q9, q13 ; output[1] = step[1] + step[2]
412 vsub.s16 q2, q9, q13 ; output[2] = step[1] - step[2]
413 vsub.s16 q3, q9, q15 ; output[3] = step[0] - step[3]
414
415 ; stage 2 - odd half
416 vsub.s16 q13, q4, q5 ; step2[5] = step1[4] - step1[5]
417 vadd.s16 q4, q4, q5 ; step2[4] = step1[4] + step1[5]
418 vsub.s16 q14, q7, q6 ; step2[6] = -step1[6] + step1[7]
419 vadd.s16 q7, q7, q6 ; step2[7] = step1[6] + step1[7]
420
421 ; step2[6] * cospi_16_64
422 vmull.s16 q9, d28, d16
423 vmull.s16 q10, d29, d16
424
425 ; step2[6] * cospi_16_64
426 vmull.s16 q11, d28, d16
427 vmull.s16 q12, d29, d16
428
429 ; (step2[6] - step2[5]) * cospi_16_64
430 vmlsl.s16 q9, d26, d16
431 vmlsl.s16 q10, d27, d16
432
433 ; (step2[5] + step2[6]) * cospi_16_64
434 vmlal.s16 q11, d26, d16
435 vmlal.s16 q12, d27, d16
436
437 ; dct_const_round_shift(input_dc * cospi_16_64)
438 vqrshrn.s32 d10, q9, #14 ; >> 14
439 vqrshrn.s32 d11, q10, #14 ; >> 14
440
441 ; dct_const_round_shift(input_dc * cospi_16_64)
442 vqrshrn.s32 d12, q11, #14 ; >> 14
443 vqrshrn.s32 d13, q12, #14 ; >> 14
444
445 ; stage 4
446 vadd.s16 q8, q0, q7 ; output[0] = step1[0] + step1[7];
447 vadd.s16 q9, q1, q6 ; output[1] = step1[1] + step1[6];
448 vadd.s16 q10, q2, q5 ; output[2] = step1[2] + step1[5];
449 vadd.s16 q11, q3, q4 ; output[3] = step1[3] + step1[4];
450 vsub.s16 q12, q3, q4 ; output[4] = step1[3] - step1[4];
451 vsub.s16 q13, q2, q5 ; output[5] = step1[2] - step1[5];
452 vsub.s16 q14, q1, q6 ; output[6] = step1[1] - step1[6];
453 vsub.s16 q15, q0, q7 ; output[7] = step1[0] - step1[7];
454
455 ; Transpose the matrix
456 TRANSPOSE8X8
457
458 ; Then transform columns
459 IDCT8x8_1D
460
461 ; ROUND_POWER_OF_TWO(temp_out[j], 5)
462 vrshr.s16 q8, q8, #5
463 vrshr.s16 q9, q9, #5
464 vrshr.s16 q10, q10, #5
465 vrshr.s16 q11, q11, #5
466 vrshr.s16 q12, q12, #5
467 vrshr.s16 q13, q13, #5
468 vrshr.s16 q14, q14, #5
469 vrshr.s16 q15, q15, #5
470
471 ; save dest pointer
472 mov r0, r1
473
474 ; load destination data
475 vld1.64 {d0}, [r1], r2
476 vld1.64 {d1}, [r1], r2
477 vld1.64 {d2}, [r1], r2
478 vld1.64 {d3}, [r1], r2
479 vld1.64 {d4}, [r1], r2
480 vld1.64 {d5}, [r1], r2
481 vld1.64 {d6}, [r1], r2
482 vld1.64 {d7}, [r1]
483
484 ; ROUND_POWER_OF_TWO(temp_out[j], 5) + dest[j * dest_stride + i]
485 vaddw.u8 q8, q8, d0
486 vaddw.u8 q9, q9, d1
487 vaddw.u8 q10, q10, d2
488 vaddw.u8 q11, q11, d3
489 vaddw.u8 q12, q12, d4
490 vaddw.u8 q13, q13, d5
491 vaddw.u8 q14, q14, d6
492 vaddw.u8 q15, q15, d7
493
494 ; clip_pixel
495 vqmovun.s16 d0, q8
496 vqmovun.s16 d1, q9
497 vqmovun.s16 d2, q10
498 vqmovun.s16 d3, q11
499 vqmovun.s16 d4, q12
500 vqmovun.s16 d5, q13
501 vqmovun.s16 d6, q14
502 vqmovun.s16 d7, q15
503
504 ; store the data
505 vst1.64 {d0}, [r0], r2
506 vst1.64 {d1}, [r0], r2
507 vst1.64 {d2}, [r0], r2
508 vst1.64 {d3}, [r0], r2
509 vst1.64 {d4}, [r0], r2
510 vst1.64 {d5}, [r0], r2
511 vst1.64 {d6}, [r0], r2
512 vst1.64 {d7}, [r0], r2
513
514 vpop {d8-d15}
515 pop {r4-r9}
516 bx lr
517 ENDP ; |vp9_idct8x8_12_add_neon|
518
519 END
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698