1/* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18/*
19
20 Pathname: ./c/include/fxp_mul32_arm_gcc.h
21
22------------------------------------------------------------------------------
23 REVISION HISTORY
24
25 Who:                                       Date:
26 Description:
27------------------------------------------------------------------------------
28 INCLUDE DESCRIPTION
29
30------------------------------------------------------------------------------
31*/
32
33#ifndef FXP_MUL32_ARM_GCC
34#define FXP_MUL32_ARM_GCC
35
36
37#ifdef __cplusplus
38extern "C"
39{
40#endif
41
42
43#include "pv_audio_type_defs.h"
44
45
46#if (defined (PV_ARM_GCC_V4) || defined(PV_ARM_GCC_V5)) /* ARM GNU COMPILER  */
47
48
49
50#define preload_cache( a)
51
52
53    static inline Int32 shft_lft_1(Int32 y)
54    {
55        register Int32 x;
56        register Int32 ra = y;
57
58
59        asm volatile(
60            "qadd %0, %1, %1\n\t"
61    : "=&r*i"(x)
62                    : "r"(ra));
63
64        return (x);
65    }
66
67    static inline Int32 fxp_mul_16_by_16bb(Int32 L_var1, const Int32 L_var2)
68    {
69
70        register Int32 tmp;
71        register Int32 ra = (Int32)L_var1;
72        register Int32 rb = (Int32)L_var2;
73
74        asm volatile(
75            "smulbb %0, %1, %2"
76    : "=&r*i"(tmp)
77                    : "r"(ra),
78                    "r"(rb));
79
80        return (tmp);
81    }
82
83
84#define fxp_mul_16_by_16(a, b)  fxp_mul_16_by_16bb(  a, b)
85
86
87    static inline Int32 fxp_mul_16_by_16tb(Int32 L_var1, const Int32 L_var2)
88{
89
90        register Int32 tmp;
91        register Int32 ra = (Int32)L_var1;
92        register Int32 rb = (Int32)L_var2;
93
94        asm volatile(
95            "smultb %0, %1, %2"
96    : "=&r*i"(tmp)
97                    : "r"(ra),
98                    "r"(rb));
99
100        return (tmp);
101    }
102
103    static inline Int32 fxp_mul_16_by_16bt(Int32 L_var1, const Int32 L_var2)
104{
105
106        register Int32 tmp;
107        register Int32 ra = (Int32)L_var1;
108        register Int32 rb = (Int32)L_var2;
109
110        asm volatile(
111            "smulbt %0, %1, %2"
112    : "=&r*i"(tmp)
113                    : "r"(ra),
114                    "r"(rb));
115
116        return (tmp);
117    }
118
119    static inline Int32 fxp_mul_16_by_16tt(Int32 L_var1, const Int32 L_var2)
120{
121
122        register Int32 tmp;
123        register Int32 ra = (Int32)L_var1;
124        register Int32 rb = (Int32)L_var2;
125
126        asm volatile(
127            "smultt %0, %1, %2"
128    : "=&r*i"(tmp)
129                    : "r"(ra),
130                    "r"(rb));
131
132        return (tmp);
133    }
134
135    static inline Int32 fxp_mac_16_by_16(const Int32 L_var1, const Int32 L_var2, Int32 L_add)
136{
137        register Int32 tmp;
138        register Int32 ra = (Int32)L_var1;
139        register Int32 rb = (Int32)L_var2;
140        register Int32 rc = (Int32)L_add;
141
142        asm volatile(
143            "smlabb %0, %1, %2, %3"
144    : "=&r*i"(tmp)
145                    : "r"(ra),
146                    "r"(rb),
147                    "r"(rc));
148
149        return (tmp);
150    }
151
152
153
154    static inline Int32 fxp_mac_16_by_16_bb(const Int32 L_var1, const Int32 L_var2, Int32 L_add)
155{
156        register Int32 tmp;
157        register Int32 ra = (Int32)L_var1;
158        register Int32 rb = (Int32)L_var2;
159        register Int32 rc = (Int32)L_add;
160
161        asm volatile(
162            "smlabb %0, %1, %2, %3"
163    : "=&r*i"(tmp)
164                    : "r"(ra),
165                    "r"(rb),
166                    "r"(rc));
167
168        return (tmp);
169    }
170
171
172    static inline Int32 fxp_mac_16_by_16_bt(const Int32 L_var1, const Int32 L_var2, Int32 L_add)
173{
174        register Int32 tmp;
175        register Int32 ra = (Int32)L_var1;
176        register Int32 rb = (Int32)L_var2;
177        register Int32 rc = (Int32)L_add;
178
179        asm volatile(
180            "smlabt %0, %1, %2, %3"
181    : "=&r*i"(tmp)
182                    : "r"(ra),
183                    "r"(rb),
184                    "r"(rc));
185
186        return (tmp);
187    }
188
189
190
191    static inline Int32 cmplx_mul32_by_16(Int32 x, const Int32 y, Int32 exp_jw)
192{
193        register Int32 cx_sum;
194        register Int32 rx = (Int32)x;
195        register Int32 ry = (Int32)y;
196        register Int32 rexp = (Int32)exp_jw;
197        asm volatile(
198            "smulwt %0, %1, %3\n\t"
199            "smlawb %0, %2, %3, %0"
200    : "=&r*i"(cx_sum)
201                    : "r"(rx),
202                    "r"(ry),
203                    "r"(rexp));
204
205        return (cx_sum);
206    }
207
208
209    static inline Int32 fxp_mul32_by_16(Int32 L_var1, const Int32 L_var2)
210{
211
212        register Int32 tmp;
213        register Int32 ra = (Int32)L_var1;
214        register Int32 rb = (Int32)L_var2;
215
216        asm volatile(
217            "smulwb %0, %1, %2"
218    : "=&r*i"(tmp)
219                    : "r"(ra),
220                    "r"(rb));
221
222        return (tmp);
223    }
224
225#define fxp_mul32_by_16b( a, b)   fxp_mul32_by_16( a, b)
226
227
228    static inline Int32 fxp_mul32_by_16t(Int32 L_var1, const Int32 L_var2)
229{
230
231        register Int32 tmp;
232        register Int32 ra = (Int32)L_var1;
233        register Int32 rb = (Int32)L_var2;
234
235        asm volatile(
236            "smulwt %0, %1, %2"
237    : "=&r*i"(tmp)
238                    : "r"(ra),
239                    "r"(rb));
240
241        return (tmp);
242    }
243
244
245
246    static inline Int32 fxp_mac32_by_16(const Int32 L_var1, const Int32 L_var2, Int32 L_add)
247{
248
249        register Int32 tmp;
250        register Int32 ra = (Int32)L_var1;
251        register Int32 rb = (Int32)L_var2;
252        register Int32 rc = (Int32)L_add;
253
254        asm volatile(
255            "smlawb %0, %1, %2, %3"
256    : "=&r*i"(tmp)
257                    : "r"(ra),
258                    "r"(rb),
259                    "r"(rc));
260
261        return (tmp);
262    }
263
264
265    __inline  int64 fxp_mac64_Q31(int64 sum, const Int32 L_var1, const Int32 L_var2)
266{
267        sum += (int64)L_var1 * L_var2;
268        return (sum);
269    }
270
271
272
273
274    static inline Int32 fxp_mac32_Q30(const Int32 a, const Int32 b, Int32 L_add)
275    {
276        Int32 result64_hi;
277        Int32 result64_lo;
278        register Int32 ra = (Int32)a;
279        register Int32 rb = (Int32)b;
280        register Int32 rc = (Int32)L_add;
281
282        asm volatile("smull %1, %0, %2, %3\n\t"
283                     "add %4, %4, %0, asl #2\n\t"
284                     "add %0, %4, %1, lsr #30"
285             : "=&r*i"(result64_hi),
286                     "=&r*i"(result64_lo)
287                             : "r"(ra),
288                             "r"(rb),
289                             "r"(rc));
290
291        return (result64_hi);
292    }
293
294
295    static inline Int32 fxp_mac32_Q31(Int32 L_add, const Int32 a, const Int32 b)
296{
297
298        Int32 result64_hi;
299        Int32 result64_lo;
300        register Int32 ra = (Int32)a;
301        register Int32 rb = (Int32)b;
302        register Int32 rc = (Int32)L_add;
303
304        asm volatile("smull %1, %0, %2, %3\n\t"
305                     "add %0, %0, %4"
306             : "=&r*i"(result64_hi),
307                     "=&r*i"(result64_lo)
308                             : "r"(ra),
309                             "r"(rb),
310                             "r"(rc));
311
312        return (result64_hi);
313    }
314
315
316
317    static inline Int32 fxp_msu32_Q31(Int32 L_sub, const Int32 a, const Int32 b)
318{
319        Int32 result64_hi;
320        Int32 result64_lo;
321        register Int32 ra = (Int32)a;
322        register Int32 rb = (Int32)b;
323        register Int32 rc = (Int32)L_sub;
324
325        asm volatile("smull %1, %0, %2, %3\n\t"
326                     "sub %0, %4, %0"
327             : "=&r*i"(result64_hi),
328                     "=&r*i"(result64_lo)
329                             : "r"(ra),
330                             "r"(rb),
331                             "r"(rc));
332
333
334        return (result64_hi);
335    }
336
337
338    static inline Int32 fxp_mul32_Q31(const Int32 a, const Int32 b)
339{
340        Int32 result64_hi;
341        Int32 result64_lo;
342        register Int32 ra = (Int32)a;
343        register Int32 rb = (Int32)b;
344        asm volatile(
345            "smull %1, %0, %2, %3"
346    : "=&r*i"(result64_hi),
347            "=&r*i"(result64_lo)
348                    : "r"(ra),
349                    "r"(rb));
350
351        return (result64_hi);
352    }
353
354
355    static inline Int32 fxp_mul32_Q30(const Int32 a, const Int32 b)
356{
357        Int32 result64_hi;
358        Int32 result64_lo;
359        register Int32 ra = (Int32)a;
360        register Int32 rb = (Int32)b;
361        asm volatile("smull %1, %0, %2, %3\n\t"
362                     "mov %0, %0, lsl #2\n\t"
363                     "orr   %0, %0, %1, lsr #30"
364             : "=&r*i"(result64_hi),
365                     "=&r*i"(result64_lo)
366                             : "r"(ra),
367                             "r"(rb));
368        return (result64_hi);
369    }
370
371
372
373    static inline Int32 fxp_mac32_Q29(const Int32 a, const Int32 b, Int32 L_add)
374{
375        Int32 result64_hi;
376        Int32 result64_lo;
377        register Int32 ra = (Int32)a;
378        register Int32 rb = (Int32)b;
379        register Int32 rc = (Int32)L_add;
380
381        asm volatile("smull %1, %0, %2, %3\n\t"
382                     "add   %4, %4, %0, lsl #3\n\t"
383                     "add   %0, %4, %1, lsr #29"
384             : "=&r*i"(result64_hi),
385                     "=&r*i"(result64_lo)
386                             : "r"(ra),
387                             "r"(rb),
388                             "r"(rc));
389
390        return (result64_hi);
391    }
392
393
394    static inline Int32 fxp_msu32_Q29(const Int32 a, const Int32 b, Int32 L_sub)
395{
396        Int32 result64_hi;
397        Int32 result64_lo;
398        register Int32 ra = (Int32)a;
399        register Int32 rb = (Int32)b;
400        register Int32 rc = (Int32)L_sub;
401
402        asm volatile("smull %1, %0, %2, %3\n\t"
403                     "sub   %4, %4, %0, lsl #3\n\t"
404                     "sub   %0, %4, %1, lsr #29"
405             : "=&r*i"(result64_hi),
406                     "=&r*i"(result64_lo)
407                             : "r"(ra),
408                             "r"(rb),
409                             "r"(rc));
410
411        return (result64_hi);
412    }
413
414    static inline Int32 fxp_mul32_Q29(const Int32 a, const Int32 b)
415{
416        Int32 result64_hi;
417        Int32 result64_lo;
418        register Int32 ra = (Int32)a;
419        register Int32 rb = (Int32)b;
420        asm volatile("smull %1, %0, %2, %3\n\t"
421                     "mov %0, %0, lsl #3\n\t"
422                     "orr   %0, %0, %1, lsr #29"
423             : "=&r*i"(result64_hi),
424                     "=&r*i"(result64_lo)
425                             : "r"(ra),
426                             "r"(rb));
427        return (result64_hi);
428    }
429
430
431
432    static inline Int32 fxp_mul32_Q28(const Int32 a, const Int32 b)
433{
434        Int32 result64_hi;
435        Int32 result64_lo;
436        register Int32 ra = (Int32)a;
437        register Int32 rb = (Int32)b;
438        asm volatile("smull %1, %0, %2, %3\n\t"
439                     "mov %0, %0, lsl #4\n\t"
440                     "orr   %0, %0, %1, lsr #28"
441             : "=&r*i"(result64_hi),
442                     "=&r*i"(result64_lo)
443                             : "r"(ra),
444                             "r"(rb));
445        return (result64_hi);
446    }
447
448    static inline Int32 fxp_mul32_Q27(const Int32 a, const Int32 b)
449{
450        Int32 result64_hi;
451        Int32 result64_lo;
452        register Int32 ra = (Int32)a;
453        register Int32 rb = (Int32)b;
454        asm volatile("smull %1, %0, %2, %3\n\t"
455                     "mov %0, %0, lsl #5\n\t"
456                     "orr   %0, %0, %1, lsr #27"
457             : "=&r*i"(result64_hi),
458                     "=&r*i"(result64_lo)
459                             : "r"(ra),
460                             "r"(rb));
461
462        return (result64_hi);
463    }
464
465
466    static inline Int32 fxp_mul32_Q26(const Int32 a, const Int32 b)
467{
468        Int32 result64_hi;
469        Int32 result64_lo;
470        register Int32 ra = (Int32)a;
471        register Int32 rb = (Int32)b;
472        asm volatile("smull %1, %0, %2, %3\n\t"
473                     "mov %0, %0, lsl #6\n\t"
474                     "orr   %0, %0, %1, lsr #26"
475             : "=&r*i"(result64_hi),
476                     "=&r*i"(result64_lo)
477                             : "r"(ra),
478                             "r"(rb));
479
480        return (result64_hi);
481    }
482
483
484    static inline Int32 fxp_mul32_Q20(const Int32 a, const Int32 b)
485{
486        Int32 result64_hi;
487        Int32 result64_lo;
488        register Int32 ra = (Int32)a;
489        register Int32 rb = (Int32)b;
490        asm volatile("smull %1, %0, %2, %3\n\t"
491                     "mov %0, %0, lsl #12\n\t"
492                     "orr   %0, %0, %1, lsr #20"
493             : "=&r*i"(result64_hi),
494                     "=&r*i"(result64_lo)
495                             : "r"(ra),
496                             "r"(rb));
497
498        return (result64_hi);
499    }
500
501
502    static inline Int32 fxp_mul32_Q15(const Int32 a, const Int32 b)
503{
504        Int32 result64_hi;
505        Int32 result64_lo;
506        register Int32 ra = (Int32)a;
507        register Int32 rb = (Int32)b;
508        asm volatile("smull %1, %0, %2, %3\n\t"
509                     "mov %0, %0, lsl #17\n\t"
510                     "orr   %0, %0, %1, lsr #15"
511             : "=&r*i"(result64_hi),
512                     "=&r*i"(result64_lo)
513                             : "r"(ra),
514                             "r"(rb));
515
516        return (result64_hi);
517    }
518
519
520
521    static inline Int32 fxp_mul32_Q14(const Int32 a, const Int32 b)
522{
523        Int32 result64_hi;
524        Int32 result64_lo;
525        register Int32 ra = (Int32)a;
526        register Int32 rb = (Int32)b;
527        asm volatile("smull %1, %0, %2,  %3\n\t"
528                     "mov   %0, %0, lsl #18\n\t"
529                     "orr   %0, %0, %1, lsr #14"
530             : "=&r*i"(result64_hi),
531                     "=&r*i"(result64_lo)
532                             : "r"(ra),
533                             "r"(rb));
534
535        return (result64_hi);
536    }
537
538#endif
539
540
541#ifdef __cplusplus
542}
543#endif
544
545
546#endif   /*  FXP_MUL32  */
547
548