add True Audio (TTA) codec
[kugel-rb.git] / apps / codecs / libtta / filter_arm.S
blob37c515d3a9569af1e28497ef91d4e77f139b6c82
1 /***************************************************************************
2  *             __________               __   ___.
3  *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
4  *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
5  *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
6  *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
7  *                     \/            \/     \/    \/            \/
8  * $Id$
9  *
10  * Copyright (C) 2010 Yoshihisa Uchida
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18  * KIND, either express or implied.
19  *
20  ****************************************************************************/
22 #include "config.h"
25  * The following are assembler optimised version of
26  * void hybrid_filter(fltst *fs, int *in)
27  */
29 #ifdef USE_IRAM
30     .section .icode, "ax", %progbits
31 #else
32     .text
33 #endif
34     .align
35     .global  hybrid_filter
36     .type    hybrid_filter, %function
38 hybrid_filter:
39     @ input: r0 = fs, r1 = in
40     stmdb    sp!, {r4 - r12, lr}
42     @ get fs members
43     @ r2 pA  := fs->dl + fs->index
44     @ r3 pM  := fs->dx + fs->index
45     @ r4 pB  := fs->qm
46     @ r5 fs->index
47     @ r6 fs->error
48     @ lr sum := fs->round
50     add      r2,  r0, #148                       @ r2 = fs->dl
51     add      r3,  r0, #52                        @ r3 = fs->dx
52     add      r4,  r0, #20                        @ r4 = fs->qm
53     ldmia    r0,  {r5, r6, lr}                   @ r5 = fs->index
54                                                  @ r6 = fs->error
55                                                  @ lr = fs->round
56     mov      r5,  r5, asl #2
57     add      r2,  r2, r5                         @ r2 = fs->dl + fs->index
58     add      r3,  r3, r5                         @ r3 = fs->dx + fs->index
60     cmp      r6,  #0
61     bne      .hf_positive
63     @ case fs->error == 0
65     add      r3,  r3, #32
66     ldmia    r4!, {r5, r6,  r7,  r8 }
67     ldmia    r2!, {r9, r10, r11, r12}
68     mla      lr,  r5, r9,  lr
69     mla      lr,  r6, r10, lr
70     mla      lr,  r7, r11, lr
71     mla      lr,  r8, r12, lr
72     ldmia    r4!, {r5, r6,  r7,  r8 }
73     b        .hf2
75 .hf_positive:
76     blt      .hf_negative
78     @ case fs->error > 0
80     ldmia    r4,  {r5, r6,  r7,  r8 }
81     ldmia    r3!, {r9, r10, r11, r12}
82     add      r5,  r5, r9
83     add      r6,  r6, r10
84     add      r7,  r7, r11
85     add      r8,  r8, r12
86     stmia    r4!, {r5, r6,  r7,  r8 }            @ update fs->qm[0], ..., fs->qm[3]
87     ldmia    r2!, {r9, r10, r11, r12}
88     mla      lr,  r5, r9,  lr
89     mla      lr,  r6, r10, lr
90     mla      lr,  r7, r11, lr
91     mla      lr,  r8, r12, lr
92     ldmia    r4,  {r5, r6,  r7,  r8 }
93     ldmia    r3!, {r9, r10, r11, r12}
94     add      r5,  r5, r9
95     add      r6,  r6, r10
96     add      r7,  r7, r11
97     add      r8,  r8, r12
98     stmia    r4!, {r5, r6,  r7,  r8 }            @ update fs->qm[4], ..., fs->qm[7]
99     b .hf2
101 .hf_negative:
102     @ case fs->error < 0
104     ldmia    r4,  {r5, r6,  r7,  r8 }
105     ldmia    r3!, {r9, r10, r11, r12}
106     sub      r5,  r5, r9
107     sub      r6,  r6, r10
108     sub      r7,  r7, r11
109     sub      r8,  r8, r12
110     stmia    r4!, {r5, r6,  r7,  r8 }            @ update fs->qm[0], ..., fs->qm[3]
111     ldmia    r2!, {r9, r10, r11, r12}
112     mla      lr,  r5, r9,  lr
113     mla      lr,  r6, r10, lr
114     mla      lr,  r7, r11, lr
115     mla      lr,  r8, r12, lr
116     ldmia    r4,  {r5, r6,  r7,  r8 }
117     ldmia    r3!, {r9, r10, r11, r12}
118     sub      r5,  r5, r9
119     sub      r6,  r6, r10
120     sub      r7,  r7, r11
121     sub      r8,  r8, r12
122     stmia    r4!, {r5, r6,  r7,  r8 }            @ update fs->qm[4], ..., fs->qm[7]
124 .hf2:
125     ldmia    r2!, {r9, r10, r11, r12}
126     mla      lr,  r5, r9,  lr
127     mla      lr,  r6, r10, lr
128     mla      lr,  r7, r11, lr
129     mla      lr,  r8, r12, lr
131     @ fs->error = *in;
132     @ *in += (sum >> fs->shift)
133     @ *pA = *in
135     ldr      r5,  [r1]                           @ r5 = *in
136     ldr      r6,  [r0, #12]                      @ r6 = fs->shift
137     add      lr,  r5, lr, asr r6
138     str      lr,  [r1]                           @ *in += (sum >> fs->shift)
140     @ update fs->index
142     ldr      r1,  [r0]                           @ r1 = fs->index
143     add      r1,  r1,  #1
144     ands     r1,  r1,  #15                       @ set Z flag (after this, CPSR must keep !!)
145     stmia    r0,  {r1, r5}                       @ fs->index = (++fs->index & 15)
146                                                  @ fs->error = (original) *in
148     @ change *pM, *(pM-1), *(pM-2), *(pM-3)
149     @ r9  = *(pA-4), r5 = *(pM-3)
150     @ r10 = *(pA-3), r6 = *(pM-2)
151     @ r11 = *(pA-2), r7 = *(pM-1)
152     @ r12 = *(pA-1), r8 = *(pM-0)
153     @ lr  = *(pA-0)
155     mov      r4,  #1
156     orr      r5,  r4, r9,  asr #30
157     orr      r6,  r4, r10, asr #30
158     orr      r7,  r4, r11, asr #30
159     orr      r8,  r4, r12, asr #30
160     mov      r6,  r6, lsl #1
161     mov      r7,  r7, lsl #1
162     mov      r8,  r8, lsl #2
164     @ change *(pA-1), *(pA-2), *(pA-3)
165     sub      r12, lr,  r12
166     sub      r11, r12, r11
167     sub      r10, r11, r10
169     @ check fs->index is zero
170     beq      .hf_memshl
172     @ set to the memory: *pA, *(pA-1), *(pA-2), *(pA-3), *pM, *(pM-1), *(pM-2), *(pM-3)
173     stmda    r2,  {r10, r11, r12, lr}
174     stmda    r3,  {r5,  r6,  r7,  r8}
175     ldmfd    sp!, {r4-r12, pc}                   @ hybrid_filter end (when fs->index != 0)
177 .hf_memshl:
178     @ memshl (fs->dl)
179     @ r9  = fs->dl[16 + 3]
180     @ r10 = fs->dl[16 + 4]
181     @ r11 = fs->dl[16 + 5]
182     @ r12 = fs->dl[16 + 6]
183     @ lr  = fs->dl[16 + 7]
185     add      r2,  r0,  #212                      @ r2 = fs->dl + 16
186     ldmia    r2,  {r1, r3, r4}
187     sub      r2,  r2,  #64                       @ r2 = fs->dl
188     stmia    r2,  {r1, r3, r4, r9 - r12, lr}
190     @ memshl (fs->dx)
191     @ r5 = fs->dx[16 + 4]
192     @ r6 = fs->dx[16 + 5]
193     @ r7 = fs->dx[16 + 6]
194     @ r8 = fs->dx[16 + 7]
196     add      r9,  r0,  #116                      @ r9 = fs->dx + 16
197     ldmia    r9,  {r1, r2, r3, r4}
198     sub      r9,  r9,  #64                       @ r9 = fs->dx
199     stmia    r9,  {r1 - r8}
200     ldmfd    sp!, {r4 - r12, pc}                 @ hybrid_filter end (when fs->index == 0)
202 hybrid_filter_end:
203     .size    hybrid_filter, hybrid_filter_end - hybrid_filter