f7fd5c7bde29e459f684c0865dcc6f109a1c6ca3
[ffmpeg.git] / libavcodec / arm / jrevdct_arm.S
1 /*
2    C-like prototype :
3         void j_rev_dct_arm(DCTBLOCK data)
4
5    With DCTBLOCK being a pointer to an array of 64 'signed shorts'
6
7    Copyright (c) 2001 Lionel Ulmer (lionel.ulmer@free.fr / bbrox@bbrox.org)
8
9    Permission is hereby granted, free of charge, to any person obtaining a copy
10    of this software and associated documentation files (the "Software"), to deal
11    in the Software without restriction, including without limitation the rights
12    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13    copies of the Software, and to permit persons to whom the Software is
14    furnished to do so, subject to the following conditions:
15
16    The above copyright notice and this permission notice shall be included in
17    all copies or substantial portions of the Software.
18
19    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
22    COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
23    IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24    CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26 */
27
28 #include "asm.S"
29
30 #define FIX_0_298631336 2446
31 #define FIX_0_541196100 4433
32 #define FIX_0_765366865 6270
33 #define FIX_1_175875602 9633
34 #define FIX_1_501321110 12299
35 #define FIX_2_053119869 16819
36 #define FIX_3_072711026 25172
37 #define FIX_M_0_390180644 -3196
38 #define FIX_M_0_899976223 -7373
39 #define FIX_M_1_847759065 -15137
40 #define FIX_M_1_961570560 -16069
41 #define FIX_M_2_562915447 -20995
42 #define FIX_0xFFFF 0xFFFF
43
44 #define FIX_0_298631336_ID      0
45 #define FIX_0_541196100_ID      4
46 #define FIX_0_765366865_ID      8
47 #define FIX_1_175875602_ID     12
48 #define FIX_1_501321110_ID     16
49 #define FIX_2_053119869_ID     20
50 #define FIX_3_072711026_ID     24
51 #define FIX_M_0_390180644_ID   28
52 #define FIX_M_0_899976223_ID   32
53 #define FIX_M_1_847759065_ID   36
54 #define FIX_M_1_961570560_ID   40
55 #define FIX_M_2_562915447_ID   44
56 #define FIX_0xFFFF_ID          48
57
58 function ff_j_rev_dct_arm, export=1
59         stmdb   sp!, { r4 - r12, lr }   @ all callee saved regs
60         sub sp, sp, #4                  @ reserve some space on the stack
61         str r0, [ sp ]                  @ save the DCT pointer to the stack
62
63         mov lr, r0                      @ lr = pointer to the current row
64         mov r12, #8                     @ r12 = row-counter
65         movrel r11, const_array         @ r11 = base pointer to the constants array
66 row_loop:
67         ldrsh r0, [lr, # 0]             @ r0 = 'd0'
68         ldrsh r2, [lr, # 2]             @ r2 = 'd2'
69
70         @ Optimization for row that have all items except the first set to 0
71         @ (this works as the DCTELEMS are always 4-byte aligned)
72         ldr r5, [lr, # 0]
73         ldr r6, [lr, # 4]
74         ldr r3, [lr, # 8]
75         ldr r4, [lr, #12]
76         orr r3, r3, r4
77         orr r3, r3, r6
78         orrs r5, r3, r5
79         beq end_of_row_loop             @ nothing to be done as ALL of them are '0'
80         orrs r3, r3, r2
81         beq empty_row
82
83         ldrsh r1, [lr, # 8]             @ r1 = 'd1'
84         ldrsh r4, [lr, # 4]             @ r4 = 'd4'
85         ldrsh r6, [lr, # 6]             @ r6 = 'd6'
86
87         ldr r3, [r11, #FIX_0_541196100_ID]
88         add r7, r2, r6
89         ldr r5, [r11, #FIX_M_1_847759065_ID]
90         mul r7, r3, r7                      @ r7 = z1
91         ldr r3, [r11, #FIX_0_765366865_ID]
92         mla r6, r5, r6, r7                  @ r6 = tmp2
93         add r5, r0, r4                      @ r5 = tmp0
94         mla r2, r3, r2, r7                  @ r2 = tmp3
95         sub r3, r0, r4                      @ r3 = tmp1
96
97         add r0, r2, r5, lsl #13             @ r0 = tmp10
98         rsb r2, r2, r5, lsl #13             @ r2 = tmp13
99         add r4, r6, r3, lsl #13             @ r4 = tmp11
100         rsb r3, r6, r3, lsl #13             @ r3 = tmp12
101
102         stmdb   sp!, { r0, r2, r3, r4 } @ save on the stack tmp10, tmp13, tmp12, tmp11
103
104         ldrsh r3, [lr, #10]             @ r3 = 'd3'
105         ldrsh r5, [lr, #12]             @ r5 = 'd5'
106         ldrsh r7, [lr, #14]             @ r7 = 'd7'
107
108         add r0, r3, r5                        @ r0 = 'z2'
109         add r2, r1, r7                  @ r2 = 'z1'
110         add r4, r3, r7                  @ r4 = 'z3'
111         add r6, r1, r5                  @ r6 = 'z4'
112         ldr r9, [r11, #FIX_1_175875602_ID]
113         add r8, r4, r6                  @ r8 = z3 + z4
114         ldr r10, [r11, #FIX_M_0_899976223_ID]
115         mul r8, r9, r8                  @ r8 = 'z5'
116         ldr r9, [r11, #FIX_M_2_562915447_ID]
117         mul r2, r10, r2                 @ r2 = 'z1'
118         ldr r10, [r11, #FIX_M_1_961570560_ID]
119         mul r0, r9, r0                  @ r0 = 'z2'
120         ldr r9, [r11, #FIX_M_0_390180644_ID]
121         mla r4, r10, r4, r8             @ r4 = 'z3'
122         ldr r10, [r11, #FIX_0_298631336_ID]
123         mla r6, r9, r6, r8              @ r6 = 'z4'
124         ldr r9, [r11, #FIX_2_053119869_ID]
125         mla r7, r10, r7, r2             @ r7 = tmp0 + z1
126         ldr r10, [r11, #FIX_3_072711026_ID]
127         mla r5, r9, r5, r0              @ r5 = tmp1 + z2
128         ldr r9, [r11, #FIX_1_501321110_ID]
129         mla r3, r10, r3, r0             @ r3 = tmp2 + z2
130         add r7, r7, r4                  @ r7 = tmp0
131         mla r1, r9, r1, r2              @ r1 = tmp3 + z1
132         add r5,        r5, r6                  @ r5 = tmp1
133         add r3, r3, r4                  @ r3 = tmp2
134         add r1, r1, r6                  @ r1 = tmp3
135
136         ldmia sp!, { r0, r2, r4, r6 } @ r0 = tmp10 / r2 = tmp13 / r4 = tmp12 / r6 = tmp11
137                                       @ r1 = tmp3  / r3 = tmp2  / r5 = tmp1  / r7 = tmp0
138
139         @ Compute DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS)
140         add r8, r0, r1
141         add r8, r8, #(1<<10)
142         mov r8, r8, asr #11
143         strh r8, [lr, # 0]
144
145         @ Compute DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS)
146         sub r8, r0, r1
147         add r8, r8, #(1<<10)
148         mov r8, r8, asr #11
149         strh r8, [lr, #14]
150
151         @ Compute DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS)
152         add r8, r6, r3
153         add r8, r8, #(1<<10)
154         mov r8, r8, asr #11
155         strh r8, [lr, # 2]
156
157         @ Compute DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS)
158         sub r8, r6, r3
159         add r8, r8, #(1<<10)
160         mov r8, r8, asr #11
161         strh r8, [lr, #12]
162
163         @ Compute DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS)
164         add r8, r4, r5
165         add r8, r8, #(1<<10)
166         mov r8, r8, asr #11
167         strh r8, [lr, # 4]
168
169         @ Compute DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS)
170         sub r8, r4, r5
171         add r8, r8, #(1<<10)
172         mov r8, r8, asr #11
173         strh r8, [lr, #10]
174
175         @ Compute DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS)
176         add r8, r2, r7
177         add r8, r8, #(1<<10)
178         mov r8, r8, asr #11
179         strh r8, [lr, # 6]
180
181         @ Compute DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS)
182         sub r8, r2, r7
183         add r8, r8, #(1<<10)
184         mov r8, r8, asr #11
185         strh r8, [lr, # 8]
186
187         @ End of row loop
188         add lr, lr, #16
189         subs r12, r12, #1
190         bne row_loop
191         beq start_column_loop
192
193 empty_row:
194         ldr r1, [r11, #FIX_0xFFFF_ID]
195         mov r0, r0, lsl #2
196         and r0, r0, r1
197         add r0, r0, r0, lsl #16
198         str r0, [lr, # 0]
199         str r0, [lr, # 4]
200         str r0, [lr, # 8]
201         str r0, [lr, #12]
202
203 end_of_row_loop:
204         @ End of loop
205         add lr, lr, #16
206         subs r12, r12, #1
207         bne row_loop
208
209 start_column_loop:
210         @ Start of column loop
211         ldr lr, [ sp ]
212         mov r12, #8
213 column_loop:
214         ldrsh r0, [lr, #( 0*8)]             @ r0 = 'd0'
215         ldrsh r2, [lr, #( 4*8)]             @ r2 = 'd2'
216         ldrsh r4, [lr, #( 8*8)]             @ r4 = 'd4'
217         ldrsh r6, [lr, #(12*8)]             @ r6 = 'd6'
218
219         ldr r3, [r11, #FIX_0_541196100_ID]
220         add r1, r2, r6
221         ldr r5, [r11, #FIX_M_1_847759065_ID]
222         mul r1, r3, r1                      @ r1 = z1
223         ldr r3, [r11, #FIX_0_765366865_ID]
224         mla r6, r5, r6, r1                  @ r6 = tmp2
225         add r5, r0, r4                      @ r5 = tmp0
226         mla r2, r3, r2, r1                  @ r2 = tmp3
227         sub r3, r0, r4                      @ r3 = tmp1
228
229         add r0, r2, r5, lsl #13             @ r0 = tmp10
230         rsb r2, r2, r5, lsl #13             @ r2 = tmp13
231         add r4, r6, r3, lsl #13             @ r4 = tmp11
232         rsb r6, r6, r3, lsl #13             @ r6 = tmp12
233
234         ldrsh r1, [lr, #( 2*8)]             @ r1 = 'd1'
235         ldrsh r3, [lr, #( 6*8)]             @ r3 = 'd3'
236         ldrsh r5, [lr, #(10*8)]             @ r5 = 'd5'
237         ldrsh r7, [lr, #(14*8)]             @ r7 = 'd7'
238
239         @ Check for empty odd column (happens about 20 to 25 % of the time according to my stats)
240         orr r9, r1, r3
241         orr r10, r5, r7
242         orrs r10, r9, r10
243         beq empty_odd_column
244
245         stmdb   sp!, { r0, r2, r4, r6 } @ save on the stack tmp10, tmp13, tmp12, tmp11
246
247         add r0, r3, r5                  @ r0 = 'z2'
248         add r2, r1, r7                  @ r2 = 'z1'
249         add r4, r3, r7                  @ r4 = 'z3'
250         add r6, r1, r5                  @ r6 = 'z4'
251         ldr r9, [r11, #FIX_1_175875602_ID]
252         add r8, r4, r6
253         ldr r10, [r11, #FIX_M_0_899976223_ID]
254         mul r8, r9, r8                  @ r8 = 'z5'
255         ldr r9, [r11, #FIX_M_2_562915447_ID]
256         mul r2, r10, r2                 @ r2 = 'z1'
257         ldr r10, [r11, #FIX_M_1_961570560_ID]
258         mul r0, r9, r0                  @ r0 = 'z2'
259         ldr r9, [r11, #FIX_M_0_390180644_ID]
260         mla r4, r10, r4, r8             @ r4 = 'z3'
261         ldr r10, [r11, #FIX_0_298631336_ID]
262         mla r6, r9, r6, r8              @ r6 = 'z4'
263         ldr r9, [r11, #FIX_2_053119869_ID]
264         mla r7, r10, r7, r2             @ r7 = tmp0 + z1
265         ldr r10, [r11, #FIX_3_072711026_ID]
266         mla r5, r9, r5, r0              @ r5 = tmp1 + z2
267         ldr r9, [r11, #FIX_1_501321110_ID]
268         mla r3, r10, r3, r0             @ r3 = tmp2 + z2
269         add r7, r7, r4                  @ r7 = tmp0
270         mla r1, r9, r1, r2              @ r1 = tmp3 + z1
271         add r5,        r5, r6                  @ r5 = tmp1
272         add r3, r3, r4                  @ r3 = tmp2
273         add r1, r1, r6                  @ r1 = tmp3
274
275         ldmia sp!, { r0, r2, r4, r6 } @ r0 = tmp10 / r2 = tmp13 / r4 = tmp11 / r6 = tmp12
276                                       @ r1 = tmp3  / r3 = tmp2  / r5 = tmp1  / r7 = tmp0
277
278         @ Compute DESCALE(tmp10 + tmp3, CONST_BITS+PASS1_BITS+3)
279         add r8, r0, r1
280         add r8, r8, #(1<<17)
281         mov r8, r8, asr #18
282         strh r8, [lr, #( 0*8)]
283
284         @ Compute DESCALE(tmp10 - tmp3, CONST_BITS+PASS1_BITS+3)
285         sub r8, r0, r1
286         add r8, r8, #(1<<17)
287         mov r8, r8, asr #18
288         strh r8, [lr, #(14*8)]
289
290         @ Compute DESCALE(tmp11 + tmp2, CONST_BITS+PASS1_BITS+3)
291         add r8, r4, r3
292         add r8, r8, #(1<<17)
293         mov r8, r8, asr #18
294         strh r8, [lr, #( 2*8)]
295
296         @ Compute DESCALE(tmp11 - tmp2, CONST_BITS+PASS1_BITS+3)
297         sub r8, r4, r3
298         add r8, r8, #(1<<17)
299         mov r8, r8, asr #18
300         strh r8, [lr, #(12*8)]
301
302         @ Compute DESCALE(tmp12 + tmp1, CONST_BITS+PASS1_BITS+3)
303         add r8, r6, r5
304         add r8, r8, #(1<<17)
305         mov r8, r8, asr #18
306         strh r8, [lr, #( 4*8)]
307
308         @ Compute DESCALE(tmp12 - tmp1, CONST_BITS+PASS1_BITS+3)
309         sub r8, r6, r5
310         add r8, r8, #(1<<17)
311         mov r8, r8, asr #18
312         strh r8, [lr, #(10*8)]
313
314         @ Compute DESCALE(tmp13 + tmp0, CONST_BITS+PASS1_BITS+3)
315         add r8, r2, r7
316         add r8, r8, #(1<<17)
317         mov r8, r8, asr #18
318         strh r8, [lr, #( 6*8)]
319
320         @ Compute DESCALE(tmp13 - tmp0, CONST_BITS+PASS1_BITS+3)
321         sub r8, r2, r7
322         add r8, r8, #(1<<17)
323         mov r8, r8, asr #18
324         strh r8, [lr, #( 8*8)]
325
326         @ End of row loop
327         add lr, lr, #2
328         subs r12, r12, #1
329         bne column_loop
330         beq the_end
331
332 empty_odd_column:
333         @ Compute DESCALE(tmp10 + tmp3, CONST_BITS+PASS1_BITS+3)
334         @ Compute DESCALE(tmp10 - tmp3, CONST_BITS+PASS1_BITS+3)
335         add r0, r0, #(1<<17)
336         mov r0, r0, asr #18
337         strh r0, [lr, #( 0*8)]
338         strh r0, [lr, #(14*8)]
339
340         @ Compute DESCALE(tmp11 + tmp2, CONST_BITS+PASS1_BITS+3)
341         @ Compute DESCALE(tmp11 - tmp2, CONST_BITS+PASS1_BITS+3)
342         add r4, r4, #(1<<17)
343         mov r4, r4, asr #18
344         strh r4, [lr, #( 2*8)]
345         strh r4, [lr, #(12*8)]
346
347         @ Compute DESCALE(tmp12 + tmp1, CONST_BITS+PASS1_BITS+3)
348         @ Compute DESCALE(tmp12 - tmp1, CONST_BITS+PASS1_BITS+3)
349         add r6, r6, #(1<<17)
350         mov r6, r6, asr #18
351         strh r6, [lr, #( 4*8)]
352         strh r6, [lr, #(10*8)]
353
354         @ Compute DESCALE(tmp13 + tmp0, CONST_BITS+PASS1_BITS+3)
355         @ Compute DESCALE(tmp13 - tmp0, CONST_BITS+PASS1_BITS+3)
356         add r2, r2, #(1<<17)
357         mov r2, r2, asr #18
358         strh r2, [lr, #( 6*8)]
359         strh r2, [lr, #( 8*8)]
360
361         @ End of row loop
362         add lr, lr, #2
363         subs r12, r12, #1
364         bne column_loop
365
366 the_end:
367         @ The end....
368         add sp, sp, #4
369         ldmia   sp!, { r4 - r12, pc }   @ restore callee saved regs and return
370 endfunc
371
372 const const_array
373         .word FIX_0_298631336
374         .word FIX_0_541196100
375         .word FIX_0_765366865
376         .word FIX_1_175875602
377         .word FIX_1_501321110
378         .word FIX_2_053119869
379         .word FIX_3_072711026
380         .word FIX_M_0_390180644
381         .word FIX_M_0_899976223
382         .word FIX_M_1_847759065
383         .word FIX_M_1_961570560
384         .word FIX_M_2_562915447
385         .word FIX_0xFFFF
386 endconst