ddc37140ec404f20d8edbd184428043fe5ab9ec1
[pcsx_rearmed.git] / plugins / dfsound / arm_utils.S
1 /*
2  * (C) GraÅžvydas "notaz" Ignotas, 2011
3  *
4  * This work is licensed under the terms of any of these licenses
5  * (at your option):
6  *  - GNU GPL, version 2 or later.
7  *  - GNU LGPL, version 2.1 or later.
8  * See the COPYING file in the top-level directory.
9  */
10
11 #include "arm_features.h"
12
13 .text
14 .align 2
15
16 .macro load_varadr reg var
17 #if defined(__ARM_ARCH_7A__) && !defined(__PIC__)
18         movw    \reg, #:lower16:EVAR(\var)
19         movt    \reg, #:upper16:EVAR(\var)
20 #else
21         ldr     \reg, =EVAR(\var)
22 #endif
23 .endm
24
25 #ifdef __ARM_NEON__
26
27 FUNCTION(mix_chan): @ (int start, int count, int lv, int rv)
28     vmov.32     d14[0], r2
29     vmov.32     d14[1], r3             @ multipliers
30     mov         r12, r0
31     load_varadr r0, ChanBuf
32     load_varadr r2, SSumLR
33     add         r0, r12, lsl #2
34     add         r2, r12, lsl #3
35 0:
36     vldmia      r0!, {d0-d1}
37     vldmia      r2, {d2-d5}
38     vmul.s32    d10, d14, d0[0]
39     vmul.s32    d11, d14, d0[1]
40     vmul.s32    d12, d14, d1[0]
41     vmul.s32    d13, d14, d1[1]
42     vsra.s32    q1, q5, #14
43     vsra.s32    q2, q6, #14
44     subs        r1, #4
45     blt         mc_finish
46     vstmia      r2!, {d2-d5}
47     bgt         0b
48     nop
49     bxeq        lr
50
51 mc_finish:
52     vstmia      r2!, {d2}
53     cmp         r1, #-2
54     vstmiage    r2!, {d3}
55     cmp         r1, #-1
56     vstmiage    r2!, {d4}
57     bx          lr
58
59
60 FUNCTION(mix_chan_rvb): @ (int start, int count, int lv, int rv)
61     vmov.32     d14[0], r2
62     vmov.32     d14[1], r3             @ multipliers
63     mov         r12, r0
64     load_varadr r0, ChanBuf
65     load_varadr r3, sRVBStart
66     load_varadr r2, SSumLR
67     ldr         r3, [r3]
68     add         r0, r12, lsl #2
69     add         r2, r12, lsl #3
70     add         r3, r12, lsl #3
71 0:
72     vldmia      r0!, {d0-d1}
73     vldmia      r2, {d2-d5}
74     vldmia      r3, {d6-d9}
75     vmul.s32    d10, d14, d0[0]
76     vmul.s32    d11, d14, d0[1]
77     vmul.s32    d12, d14, d1[0]
78     vmul.s32    d13, d14, d1[1]
79     vsra.s32    q1, q5, #14
80     vsra.s32    q2, q6, #14
81     vsra.s32    q3, q5, #14
82     vsra.s32    q4, q6, #14
83     subs        r1, #4
84     blt         mcr_finish
85     vstmia      r2!, {d2-d5}
86     vstmia      r3!, {d6-d9}
87     bgt         0b
88     nop
89     bxeq        lr
90
91 mcr_finish:
92     vstmia      r2!, {d2}
93     vstmia      r3!, {d6}
94     cmp         r1, #-2
95     vstmiage    r2!, {d3}
96     vstmiage    r3!, {d7}
97     cmp         r1, #-1
98     vstmiage    r2!, {d4}
99     vstmiage    r3!, {d8}
100     bx          lr
101
102 #elif defined(HAVE_ARMV5)
103
104 FUNCTION(mix_chan): @ (int start, int count, int lv, int rv)
105     stmfd       sp!, {r4-r8,lr}
106     orr         r3, r2, r3, lsl #16
107     lsl         r3, #1                 @ packed multipliers << 1
108     mov         r12, r0
109     load_varadr r0, ChanBuf
110     load_varadr r2, SSumLR
111     add         r0, r12, lsl #2
112     add         r2, r12, lsl #3
113 0:
114     ldmia       r0!, {r4,r5}
115     ldmia       r2, {r6-r8,lr}
116     lsl         r4, #1                 @ adjust for mul
117     lsl         r5, #1
118     smlawb      r6, r4, r3, r6
119     smlawt      r7, r4, r3, r7
120     smlawb      r8, r5, r3, r8
121     smlawt      lr, r5, r3, lr
122     subs        r1, #2
123     blt         mc_finish
124     stmia       r2!, {r6-r8,lr}
125     bgt         0b
126     ldmeqfd     sp!, {r4-r8,pc}
127
128 mc_finish:
129     stmia       r2!, {r6,r7}
130     ldmfd       sp!, {r4-r8,pc}
131
132
133 FUNCTION(mix_chan_rvb): @ (int start, int count, int lv, int rv)
134     stmfd       sp!, {r4-r8,lr}
135     orr         lr, r2, r3, lsl #16
136     lsl         lr, #1
137     load_varadr r3, sRVBStart
138     load_varadr r2, SSumLR
139     load_varadr r4, ChanBuf
140     ldr         r3, [r3]
141     add         r2, r2, r0, lsl #3
142     add         r3, r3, r0, lsl #3
143     add         r0, r4, r0, lsl #2
144 0:
145     ldr         r4, [r0], #4
146     ldmia       r2, {r6,r7}
147     ldmia       r3, {r8,r12}
148     lsl         r4, #1
149     smlawb      r6, r4, lr, r6         @ supposedly takes single cycle?
150     smlawt      r7, r4, lr, r7
151     smlawb      r8, r4, lr, r8
152     smlawt      r12,r4, lr, r12
153     subs        r1, #1
154     stmia       r2!, {r6,r7}
155     stmia       r3!, {r8,r12}
156     bgt         0b
157     ldmfd       sp!, {r4-r8,pc}
158
159 #endif
160
161 @ vim:filetype=armasm