summaryrefslogtreecommitdiff
path: root/plugins/wma/libwma/asm_arm.h
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/wma/libwma/asm_arm.h')
-rw-r--r--plugins/wma/libwma/asm_arm.h292
1 files changed, 292 insertions, 0 deletions
diff --git a/plugins/wma/libwma/asm_arm.h b/plugins/wma/libwma/asm_arm.h
new file mode 100644
index 00000000..8e5d0e68
--- /dev/null
+++ b/plugins/wma/libwma/asm_arm.h
@@ -0,0 +1,292 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: arm7 and later wide math functions
+
+ ********************************************************************/
+#ifdef CPU_ARM
+
+#define INCL_OPTIMIZED_MULT32
+#if ARM_ARCH >= 6
+static inline int32_t MULT32(int32_t x, int32_t y) {
+ int32_t hi;
+ asm volatile("smmul %[hi], %[x], %[y] \n\t"
+ : [hi] "=&r" (hi)
+ : [x] "r" (x), [y] "r" (y) );
+ return(hi);
+}
+#else
+static inline int32_t MULT32(int32_t x, int32_t y) {
+ int32_t lo, hi;
+ asm volatile("smull\t%0, %1, %2, %3 \n\t"
+ : "=&r"(lo),"=&r"(hi)
+ : "r"(x),"r"(y) );
+ return(hi);
+}
+#endif
+
+#define INCL_OPTIMIZED_MULT31
+static inline int32_t MULT31(int32_t x, int32_t y) {
+ return MULT32(x,y)<<1;
+}
+
+#define INCL_OPTIMIZED_MULT31_SHIFT15
+static inline int32_t MULT31_SHIFT15(int32_t x, int32_t y) {
+ int32_t lo,hi;
+ asm volatile("smull %0, %1, %2, %3\n\t"
+ "movs %0, %0, lsr #15\n\t"
+ "adc %1, %0, %1, lsl #17\n\t"
+ : "=&r"(lo),"=&r"(hi)
+ : "r"(x),"r"(y)
+ : "cc" );
+ return(hi);
+}
+
+#define INCL_OPTIMIZED_MULT31_SHIFT16
+static inline int32_t MULT31_SHIFT16(int32_t x, int32_t y) {
+ int32_t lo,hi;
+ asm volatile("smull %0, %1, %2, %3\n\t"
+ "movs %0, %0, lsr #16\n\t"
+ "adc %1, %0, %1, lsl #16\n\t"
+ : "=&r"(lo),"=&r"(hi)
+ : "r"(x),"r"(y)
+ : "cc" );
+ return(hi);
+}
+
+#define INCL_OPTIMIZED_XPROD32
+#define XPROD32(a, b, t, v, x, y) \
+{ \
+ int32_t l; \
+ asm("smull %0, %1, %3, %5\n\t" \
+ "rsb %2, %6, #0\n\t" \
+ "smlal %0, %1, %4, %6\n\t" \
+ "smull %0, %2, %3, %2\n\t" \
+ "smlal %0, %2, %4, %5" \
+ : "=&r" (l), "=&r" (x), "=&r" (y) \
+ : "r" ((a)), "r" ((b)), "r" ((t)), "r" ((v)) ); \
+}
+
+#define INCL_OPTIMIZED_XPROD31_R
+#define INCL_OPTIMIZED_XNPROD31_R
+#if ARM_ARCH >= 6
+/* These may yield slightly different result from the macros below
+ because only the high 32 bits of the multiplications are accumulated while
+ the below macros use a 64 bit accumulator that is truncated to 32 bits.*/
+#define XPROD31_R(_a, _b, _t, _v, _x, _y)\
+{\
+ int32_t x1, y1;\
+ asm("smmul %[x1], %[t], %[a] \n\t"\
+ "smmul %[y1], %[t], %[b] \n\t"\
+ "smmla %[x1], %[v], %[b], %[x1] \n\t"\
+ "smmls %[y1], %[v], %[a], %[y1] \n\t"\
+ : [x1] "=&r" (x1), [y1] "=&r" (y1)\
+ : [a] "r" (_a), [b] "r" (_b), [t] "r" (_t), [v] "r" (_v) );\
+ _x = x1 << 1;\
+ _y = y1 << 1;\
+}
+
+#define XNPROD31_R(_a, _b, _t, _v, _x, _y)\
+{\
+ int32_t x1, y1;\
+ asm("smmul %[x1], %[t], %[a] \n\t"\
+ "smmul %[y1], %[t], %[b] \n\t"\
+ "smmls %[x1], %[v], %[b], %[x1] \n\t"\
+ "smmla %[y1], %[v], %[a], %[y1] \n\t"\
+ : [x1] "=&r" (x1), [y1] "=&r" (y1)\
+ : [a] "r" (_a), [b] "r" (_b), [t] "r" (_t), [v] "r" (_v) );\
+ _x = x1 << 1;\
+ _y = y1 << 1;\
+}
+#else
+#define XPROD31_R(_a, _b, _t, _v, _x, _y)\
+{\
+ int32_t x1, y1, l;\
+ asm("smull %0, %1, %5, %3\n\t"\
+ "rsb %2, %3, #0\n\t"\
+ "smlal %0, %1, %6, %4\n\t"\
+ "smull %0, %2, %6, %2\n\t"\
+ "smlal %0, %2, %5, %4"\
+ : "=&r" (l), "=&r" (x1), "=&r" (y1)\
+ : "r" (_a), "r" (_b), "r" (_t), "r" (_v) );\
+ _x = x1 << 1;\
+ _y = y1 << 1;\
+}
+
+#define XNPROD31_R(_a, _b, _t, _v, _x, _y)\
+{\
+ int32_t x1, y1, l;\
+ asm("smull %0, %1, %5, %3\n\t"\
+ "rsb %2, %4, #0\n\t"\
+ "smlal %0, %1, %6, %2\n\t"\
+ "smull %0, %2, %5, %4\n\t"\
+ "smlal %0, %2, %6, %3"\
+ : "=&r" (l), "=&r" (x1), "=&r" (y1)\
+ : "r" (_a), "r" (_b), "r" (_t), "r" (_v) );\
+ _x = x1 << 1;\
+ _y = y1 << 1;\
+}
+#endif
+
+#define INCL_OPTIMIZED_XPROD31
+static inline void XPROD31(int32_t a, int32_t b,
+ int32_t t, int32_t v,
+ int32_t *x, int32_t *y)
+{
+ int32_t _x1, _y1;
+ XPROD31_R(a, b, t, v, _x1, _y1);
+ *x = _x1;
+ *y = _y1;
+}
+
+#define INCL_OPTIMIZED_XNPROD31
+static inline void XNPROD31(int32_t a, int32_t b,
+ int32_t t, int32_t v,
+ int32_t *x, int32_t *y)
+{
+ int32_t _x1, _y1;
+ XNPROD31_R(a, b, t, v, _x1, _y1);
+ *x = _x1;
+ *y = _y1;
+}
+
+
+#ifndef _V_VECT_OPS
+#define _V_VECT_OPS
+
+/* asm versions of vector operations for block.c, window.c */
+static inline
+void vect_add(int32_t *x, const int32_t *y, int n)
+{
+ while (n>=4) {
+ asm volatile ("ldmia %[x], {r0, r1, r2, r3};"
+ "ldmia %[y]!, {r4, r5, r6, r7};"
+ "add r0, r0, r4;"
+ "add r1, r1, r5;"
+ "add r2, r2, r6;"
+ "add r3, r3, r7;"
+ "stmia %[x]!, {r0, r1, r2, r3};"
+ : [x] "+r" (x), [y] "+r" (y)
+ : : "r0", "r1", "r2", "r3",
+ "r4", "r5", "r6", "r7",
+ "memory");
+ n -= 4;
+ }
+ /* add final elements */
+ while (n>0) {
+ *x++ += *y++;
+ n--;
+ }
+}
+
+static inline
+void vect_copy(int32_t *x, const int32_t *y, int n)
+{
+ while (n>=4) {
+ asm volatile ("ldmia %[y]!, {r0, r1, r2, r3};"
+ "stmia %[x]!, {r0, r1, r2, r3};"
+ : [x] "+r" (x), [y] "+r" (y)
+ : : "r0", "r1", "r2", "r3",
+ "memory");
+ n -= 4;
+ }
+ /* copy final elements */
+ while (n>0) {
+ *x++ = *y++;
+ n--;
+ }
+}
+
+static inline
+void vect_mult_fw(int32_t *data, const int32_t *window, int n)
+{
+ while (n>=4) {
+ asm volatile ("ldmia %[d], {r0, r1, r2, r3};"
+ "ldmia %[w]!, {r4, r5, r6, r7};"
+ "smull r8, r9, r0, r4;"
+ "mov r0, r9, lsl #1;"
+ "smull r8, r9, r1, r5;"
+ "mov r1, r9, lsl #1;"
+ "smull r8, r9, r2, r6;"
+ "mov r2, r9, lsl #1;"
+ "smull r8, r9, r3, r7;"
+ "mov r3, r9, lsl #1;"
+ "stmia %[d]!, {r0, r1, r2, r3};"
+ : [d] "+r" (data), [w] "+r" (window)
+ : : "r0", "r1", "r2", "r3",
+ "r4", "r5", "r6", "r7", "r8", "r9",
+ "memory" );
+ n -= 4;
+ }
+ while(n>0) {
+ *data = MULT31(*data, *window);
+ data++;
+ window++;
+ n--;
+ }
+}
+
+static inline
+void vect_mult_bw(int32_t *data, const int32_t *window, int n)
+{
+ while (n>=4) {
+ asm volatile ("ldmia %[d], {r0, r1, r2, r3};"
+ "ldmda %[w]!, {r4, r5, r6, r7};"
+ "smull r8, r9, r0, r7;"
+ "mov r0, r9, lsl #1;"
+ "smull r8, r9, r1, r6;"
+ "mov r1, r9, lsl #1;"
+ "smull r8, r9, r2, r5;"
+ "mov r2, r9, lsl #1;"
+ "smull r8, r9, r3, r4;"
+ "mov r3, r9, lsl #1;"
+ "stmia %[d]!, {r0, r1, r2, r3};"
+ : [d] "+r" (data), [w] "+r" (window)
+ : : "r0", "r1", "r2", "r3",
+ "r4", "r5", "r6", "r7", "r8", "r9",
+ "memory" );
+ n -= 4;
+ }
+ while(n>0) {
+ *data = MULT31(*data, *window);
+ data++;
+ window--;
+ n--;
+ }
+}
+
+#endif
+
+/* not used anymore */
+/*
+#ifndef _V_CLIP_MATH
+#define _V_CLIP_MATH
+
+static inline int32_t CLIP_TO_15(int32_t x) {
+ int tmp;
+ asm volatile("subs %1, %0, #32768\n\t"
+ "movpl %0, #0x7f00\n\t"
+ "orrpl %0, %0, #0xff\n"
+ "adds %1, %0, #32768\n\t"
+ "movmi %0, #0x8000"
+ : "+r"(x),"=r"(tmp)
+ :
+ : "cc");
+ return(x);
+}
+
+#endif
+*/
+
+#endif
+