Using SSAT in SIG2WORD16() on ARMv6
authorJean-Marc Valin <jmvalin@jmvalin.ca>
Thu, 23 Jan 2014 00:22:05 +0000 (19:22 -0500)
committerJean-Marc Valin <jmvalin@jmvalin.ca>
Thu, 23 Jan 2014 00:22:05 +0000 (19:22 -0500)
celt/arch.h
celt/arm/fixed_armv5e.h
celt/celt_decoder.c
celt/fixed_generic.h

index c910c80..9f74ddd 100644 (file)
@@ -226,6 +226,8 @@ static OPUS_INLINE int celt_isnan(float x)
 #define SCALEIN(a)      ((a)*CELT_SIG_SCALE)
 #define SCALEOUT(a)     ((a)*(1/CELT_SIG_SCALE))
 
+#define SIG2WORD16(x) (x)
+
 #endif /* !FIXED_POINT */
 
 #ifndef GLOBAL_STACK_SIZE
index 36d6bed..36a6321 100644 (file)
@@ -130,4 +130,22 @@ static OPUS_INLINE opus_val32 MULT16_16_armv5e(opus_val16 a, opus_val16 b)
 }
 #define MULT16_16(a, b) (MULT16_16_armv5e(a, b))
 
+#ifdef OPUS_ARM_INLINE_MEDIA
+
+#undef SIG2WORD16
+static OPUS_INLINE opus_val16 SIG2WORD16_armv6(opus_val32 x)
+{
+   celt_sig res;
+   __asm__(
+       "#SIG2WORD16\n\t"
+       "ssat %0, #16, %1, ASR #12\n\t"
+       : "=r"(res)
+       : "r"(x+2048)
+   );
+   return EXTRACT16(res);
+}
+#define SIG2WORD16(x) (SIG2WORD16_armv6(x))
+
+#endif /* OPUS_ARM_INLINE_MEDIA */
+
 #endif
index 1e41ec1..8af96b7 100644 (file)
@@ -178,17 +178,6 @@ void opus_custom_decoder_destroy(CELTDecoder *st)
 }
 #endif /* CUSTOM_MODES */
 
-static OPUS_INLINE opus_val16 SIG2WORD16(celt_sig x)
-{
-#ifdef FIXED_POINT
-   x = PSHR32(x, SIG_SHIFT);
-   x = MAX32(x, -32768);
-   x = MIN32(x, 32767);
-   return EXTRACT16(x);
-#else
-   return (opus_val16)x;
-#endif
-}
 
 #ifndef RESYNTH
 static
index 8d13fde..5ea1c7b 100644 (file)
 /** Divide a 32-bit value by a 32-bit value. Result fits in 32 bits */
 #define DIV32(a,b) (((opus_val32)(a))/((opus_val32)(b)))
 
+static OPUS_INLINE opus_val16 SIG2WORD16_generic(celt_sig x)
+{
+   x = PSHR32(x, SIG_SHIFT);
+   x = MAX32(x, -32768);
+   x = MIN32(x, 32767);
+   return EXTRACT16(x);
+}
+#define SIG2WORD16(x) (SIG2WORD16_generic(x))
+
 #endif