1 /********************************************************************
3 * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
5 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
6 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
7 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
9 * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
10 * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
12 ********************************************************************
14 function: arm7 and later wide math functions
16 ********************************************************************/
19 #if !defined(_V_WIDE_MATH) && !defined(_LOW_ACCURACY_)
22 static inline int32_t MULT32(int32_t x
, int32_t y
) {
24 asm volatile("smull\t%0, %1, %2, %3"
30 static inline int32_t MULT31(int32_t x
, int32_t y
) {
31 return MULT32(x
,y
)<<1;
34 static inline int32_t MULT31_SHIFT15(int32_t x
, int32_t y
) {
36 asm volatile("smull %0, %1, %2, %3\n\t"
37 "movs %0, %0, lsr #15\n\t"
38 "adc %1, %0, %1, lsl #17\n\t"
45 #define XPROD32(a, b, t, v, x, y) \
48 asm( "smull %0, %1, %4, %6\n\t" \
49 "rsb %3, %4, #0\n\t" \
50 "smlal %0, %1, %5, %7\n\t" \
51 "smull %0, %2, %5, %6\n\t" \
52 "smlal %0, %2, %3, %7" \
53 : "=&r" (l), "=&r" (x), "=&r" (y), "=r" ((a)) \
54 : "3" ((a)), "r" ((b)), "r" ((t)), "r" ((v)) ); \
57 static inline void XPROD31(int32_t a
, int32_t b
,
59 int32_t *x
, int32_t *y
)
62 asm( "smull %0, %1, %4, %6\n\t"
64 "smlal %0, %1, %5, %7\n\t"
65 "smull %0, %2, %5, %6\n\t"
66 "smlal %0, %2, %3, %7"
67 : "=&r" (l
), "=&r" (x1
), "=&r" (y1
), "=r" (a
)
68 : "3" (a
), "r" (b
), "r" (t
), "r" (v
) );
73 static inline void XNPROD31(int32_t a
, int32_t b
,
75 int32_t *x
, int32_t *y
)
78 asm( "smull %0, %1, %3, %5\n\t"
80 "smlal %0, %1, %2, %6\n\t"
81 "smull %0, %2, %4, %5\n\t"
82 "smlal %0, %2, %3, %6"
83 : "=&r" (l
), "=&r" (x1
), "=&r" (y1
)
84 : "r" (a
), "r" (b
), "r" (t
), "r" (v
) );
92 /* asm versions of vector operations for block.c, window.c */
94 void vect_add(int32_t *x
, int32_t *y
, int n
)
97 asm volatile ("ldmia %[x], {r0, r1, r2, r3};"
98 "ldmia %[y]!, {r4, r5, r6, r7};"
103 "stmia %[x]!, {r0, r1, r2, r3};"
104 : [x
] "+r" (x
), [y
] "+r" (y
)
105 : : "r0", "r1", "r2", "r3",
106 "r4", "r5", "r6", "r7",
110 /* add final elements */
118 void vect_copy(int32_t *x
, int32_t *y
, int n
)
121 asm volatile ("ldmia %[y]!, {r0, r1, r2, r3};"
122 "stmia %[x]!, {r0, r1, r2, r3};"
123 : [x
] "+r" (x
), [y
] "+r" (y
)
124 : : "r0", "r1", "r2", "r3",
128 /* copy final elements */
136 void vect_mult_fw(int32_t *data
, int32_t *window
, int n
)
139 asm volatile ("ldmia %[d], {r0, r1, r2, r3};"
140 "ldmia %[w]!, {r4, r5, r6, r7};"
141 "smull r8, r9, r0, r4;"
142 "mov r0, r9, lsl #1;"
143 "smull r8, r9, r1, r5;"
144 "mov r1, r9, lsl #1;"
145 "smull r8, r9, r2, r6;"
146 "mov r2, r9, lsl #1;"
147 "smull r8, r9, r3, r7;"
148 "mov r3, r9, lsl #1;"
149 "stmia %[d]!, {r0, r1, r2, r3};"
150 : [d
] "+r" (data
), [w
] "+r" (window
)
151 : : "r0", "r1", "r2", "r3",
152 "r4", "r5", "r6", "r7", "r8", "r9",
157 *data
= MULT31(*data
, *window
);
165 void vect_mult_bw(int32_t *data
, int32_t *window
, int n
)
168 asm volatile ("ldmia %[d], {r0, r1, r2, r3};"
169 "ldmda %[w]!, {r4, r5, r6, r7};"
170 "smull r8, r9, r0, r7;"
171 "mov r0, r9, lsl #1;"
172 "smull r8, r9, r1, r6;"
173 "mov r1, r9, lsl #1;"
174 "smull r8, r9, r2, r5;"
175 "mov r2, r9, lsl #1;"
176 "smull r8, r9, r3, r4;"
177 "mov r3, r9, lsl #1;"
178 "stmia %[d]!, {r0, r1, r2, r3};"
179 : [d
] "+r" (data
), [w
] "+r" (window
)
180 : : "r0", "r1", "r2", "r3",
181 "r4", "r5", "r6", "r7", "r8", "r9",
186 *data
= MULT31(*data
, *window
);
200 static inline int32_t CLIP_TO_15(int32_t x
) {
202 asm volatile("subs %1, %0, #32768\n\t"
203 "movpl %0, #0x7f00\n\t"
204 "orrpl %0, %0, #0xff\n"
205 "adds %1, %0, #32768\n\t"
215 #ifndef _V_LSP_MATH_ASM
216 #define _V_LSP_MATH_ASM