Mozzi
version v2.0
sound synthesis library for Arduino
mult16x16.h
1
2
/*
3
Norbert Pozar 2009
4
http://mekonik.wordpress.com/2009/03/18/arduino-avr-gcc-multiplication/
5
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
6
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
7
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
8
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
9
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
10
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/
11
12
// longRes = intIn1 * intIn2
13
#
define
MultiU16X16to32
(
longRes
,
intIn1
,
intIn2
)
asm
14
volatile
(
\
15
"clr r26 \n\t"\
16
"mul %A1, %A2 \n\t"\
17
"movw %A0, r0 \n\t"\
18
"mul %B1, %B2 \n\t"\
19
"movw %C0, r0 \n\t"\
20
"mul %B2, %A1 \n\t"\
21
"add %B0, r0 \n\t"\
22
"adc %C0, r1 \n\t"\
23
"adc %D0, r26 \n\t"\
24
"mul %B1, %A2 \n\t"\
25
"add %B0, r0 \n\t"\
26
"adc %C0, r1 \n\t"\
27
"adc %D0, r26 \n\t"\
28
"clr r1 \n\t"
\
29
:
\
30
"=&r"
(
longRes
)
\
31
:
\
32
"a"
(
intIn1
)
,
\
33
"a"
(
intIn2
)
\
34
:
\
35
"r26"
\
36
)
37
38
// intRes = intIn1 * intIn2 >> 16
39
// uses:
40
// r26 to store 0
41
// r27 to store the uint8_t 1 of the 32bit result
42
#
define
MultiU16X16toH16
(
intRes
,
intIn1
,
intIn2
)
asm
43
volatile
(
\
44
"clr r26 \n\t"\
45
"mul %A1, %A2 \n\t"\
46
"mov r27, r1 \n\t"\
47
"mul %B1, %B2 \n\t"\
48
"movw %A0, r0 \n\t"\
49
"mul %B2, %A1 \n\t"\
50
"add r27, r0 \n\t"\
51
"adc %A0, r1 \n\t"\
52
"adc %B0, r26 \n\t"\
53
"mul %B1, %A2 \n\t"\
54
"add r27, r0 \n\t"\
55
"adc %A0, r1 \n\t"\
56
"adc %B0, r26 \n\t"\
57
"clr r1 \n\t"
\
58
:
\
59
"=&r"
(
intRes
)
\
60
:
\
61
"a"
(
intIn1
)
,
\
62
"a"
(
intIn2
)
\
63
:
\
64
"r26"
,
"r27"
\
65
)
66
67
// intRes = intIn1 * intIn2 >> 16 + round
68
// uses:
69
// r26 to store 0
70
// r27 to store the uint8_t 1 of the 32bit result
71
// 21 cycles
72
#
define
MultiU16X16toH16Round
(
intRes
,
intIn1
,
intIn2
)
asm
73
volatile
(
\
74
"clr r26 \n\t"\
75
"mul %A1, %A2 \n\t"\
76
"mov r27, r1 \n\t"\
77
"mul %B1, %B2 \n\t"\
78
"movw %A0, r0 \n\t"\
79
"mul %B2, %A1 \n\t"\
80
"add r27, r0 \n\t"\
81
"adc %A0, r1 \n\t"\
82
"adc %B0, r26 \n\t"\
83
"mul %B1, %A2 \n\t"\
84
"add r27, r0 \n\t"\
85
"adc %A0, r1 \n\t"\
86
"adc %B0, r26 \n\t"\
87
"lsl r27 \n\t"\
88
"adc %A0, r26 \n\t"\
89
"adc %B0, r26 \n\t"\
90
"clr r1 \n\t"
\
91
:
\
92
"=&r"
(
intRes
)
\
93
:
\
94
"a"
(
intIn1
)
,
\
95
"a"
(
intIn2
)
\
96
:
\
97
"r26"
,
"r27"
\
98
)
99
100
101
// signed16 * signed16
102
// 22 cycles
103
#
define
MultiS16X16to32
(
longRes
,
intIn1
,
intIn2
)
asm
104
volatile
(
\
105
"clr r26 \n\t"\
106
"mul %A1, %A2 \n\t"\
107
"movw %A0, r0 \n\t"\
108
"muls %B1, %B2 \n\t"\
109
"movw %C0, r0 \n\t"\
110
"mulsu %B2, %A1 \n\t"\
111
"sbc %D0, r26 \n\t"\
112
"add %B0, r0 \n\t"\
113
"adc %C0, r1 \n\t"\
114
"adc %D0, r26 \n\t"\
115
"mulsu %B1, %A2 \n\t"\
116
"sbc %D0, r26 \n\t"\
117
"add %B0, r0 \n\t"\
118
"adc %C0, r1 \n\t"\
119
"adc %D0, r26 \n\t"\
120
"clr r1 \n\t"
\
121
:
\
122
"=&r"
(
longRes
)
\
123
:
\
124
"a"
(
intIn1
)
,
\
125
"a"
(
intIn2
)
\
126
:
\
127
"r26"
\
128
)
129
130
131
// signed16 * signed 16 >> 16
132
#
define
MultiS16X16toH16
(
intRes
,
intIn1
,
intIn2
)
asm
133
volatile
(
\
134
"clr r26 \n\t"\
135
"mul %A1, %A2 \n\t"\
136
"mov r27, r1 \n\t"\
137
"muls %B1, %B2 \n\t"\
138
"movw %A0, r0 \n\t"\
139
"mulsu %B2, %A1 \n\t"\
140
"sbc %B0, r26 \n\t"\
141
"add r27, r0 \n\t"\
142
"adc %A0, r1 \n\t"\
143
"adc %B0, r26 \n\t"\
144
"mulsu %B1, %A2 \n\t"\
145
"sbc %B0, r26 \n\t"\
146
"add r27, r0 \n\t"\
147
"adc %A0, r1 \n\t"\
148
"adc %B0, r26 \n\t"\
149
"clr r1 \n\t"
\
150
:
\
151
"=&r"
(
intRes
)
\
152
:
\
153
"a"
(
intIn1
)
,
\
154
"a"
(
intIn2
)
\
155
:
\
156
"r26"
,
"r27"
\
157
)
158
159
// multiplies a signed and unsigned 16 bit ints with a 32 bit result
160
#
define
MultiSU16X16to32
(
longRes
,
intIn1
,
intIn2
)
asm
161
volatile
(
\
162
"clr r26 \n\t"\
163
"mul %A1, %A2 \n\t"\
164
"movw %A0, r0 \n\t"\
165
"mulsu %B1, %B2 \n\t"\
166
"movw %C0, r0 \n\t"\
167
"mul %B2, %A1 \n\t"\
168
"add %B0, r0 \n\t"\
169
"adc %C0, r1 \n\t"\
170
"adc %D0, r26 \n\t"\
171
"mulsu %B1, %A2 \n\t"\
172
"sbc %D0, r26 \n\t"\
173
"add %B0, r0 \n\t"\
174
"adc %C0, r1 \n\t"\
175
"adc %D0, r26 \n\t"\
176
"clr r1 \n\t"
\
177
:
\
178
"=&r"
(
longRes
)
\
179
:
\
180
"a"
(
intIn1
)
,
\
181
"a"
(
intIn2
)
\
182
:
\
183
"r26"
\
184
)
185
186
// multiplies signed x unsigned int and returns the highest 16 bits of the result
187
#
define
MultiSU16X16toH16
(
intRes
,
intIn1
,
intIn2
)
asm
188
volatile
(
\
189
"clr r26 \n\t"\
190
"mul %A1, %A2 \n\t"\
191
"mov r27, r1 \n\t"\
192
"mulsu %B1, %B2 \n\t"\
193
"movw %A0, r0 \n\t"\
194
"mul %B2, %A1 \n\t"\
195
"add r27, r0 \n\t"\
196
"adc %A0, r1 \n\t"\
197
"adc %B0, r26 \n\t"\
198
"mulsu %B1, %A2 \n\t"\
199
"sbc %B0, r26 \n\t"\
200
"add r27, r0 \n\t"\
201
"adc %A0, r1 \n\t"\
202
"adc %B0, r26 \n\t"\
203
"clr r1 \n\t"
\
204
:
\
205
"=&r"
(
intRes
)
\
206
:
\
207
"a"
(
intIn1
)
,
\
208
"a"
(
intIn2
)
\
209
:
\
210
"r26"
,
"r27"
\
211
)
212
213
// multiplies signed x unsigned int and returns the highest 16 bits of the result
214
// rounds the result based on the MSB of the lower 16 bits
215
// 22 cycles
216
#
define
MultiSU16X16toH16Round
(
intRes
,
intIn1
,
intIn2
)
asm
217
volatile
(
\
218
"clr r26 \n\t"\
219
"mul %A1, %A2 \n\t"\
220
"mov r27, r1 \n\t"\
221
"mulsu %B1, %B2 \n\t"\
222
"movw %A0, r0 \n\t"\
223
"mul %A1, %B2 \n\t"\
224
"add r27, r0 \n\t"\
225
"adc %A0, r1 \n\t"\
226
"adc %B0, r26 \n\t"\
227
"mulsu %B1, %A2 \n\t"\
228
"sbc %B0, r26 \n\t"\
229
"add r27, r0 \n\t"\
230
"adc %A0, r1 \n\t"\
231
"adc %B0, r26 \n\t"\
232
"lsl r27 \n\t"\
233
"adc %A0, r26 \n\t"\
234
"adc %B0, r26 \n\t"\
235
"clr r1 \n\t"
\
236
:
\
237
"=&r"
(
intRes
)
\
238
:
\
239
"a"
(
intIn1
)
,
\
240
"a"
(
intIn2
)
\
241
:
\
242
"r26"
,
"r27"
\
243
)
Generated automatically using Doxygen. If info on this page is outdated, incomplete, or wrong, please open an issue at https://github.com/sensorium/Mozzi/issues